I like to use overloading to speed up development, and I want to structure my code to make future changes easier. I have a function that accepts a NUMBER
or a VARCHAR2
, but I want it to throw a compilation error if I pass in a DATE
.
Here's an illustration of the problem I want to avoid:
DECLARE
PROCEDURE do_something(
in_ IN VARCHAR2);
PROCEDURE do_something(
in_ IN NUMBER);
mystery_variable_1 VARCHAR2(32767);
mystery_variable_2 NUMBER;
mystery_variable_3 DATE;
PROCEDURE do_something(
in_ IN VARCHAR2)
IS
BEGIN
dbms_output.put_line('do_something called with VARCHAR2 argument ' || in_);
END do_something;
PROCEDURE do_something(
in_ IN NUMBER)
IS
BEGIN
dbms_output.put_line('do_something called with NUMBER argument ' || in_);
END do_something;
BEGIN
mystery_variable_1 := 'Hello, World!';
mystery_variable_2 := 42;
mystery_variable_3 := TO_DATE('2063-04-05', 'YYYY-MM-DD');
do_something(mystery_variable_1);
do_something(mystery_variable_2);
do_something(mystery_variable_3); -- I want this to throw a compilation error.
END;
/
Here's the output showing the implicit cast from DATE
to VARCHAR2
:
do_something called with VARCHAR2 argument Hello, World!
do_something called with NUMBER argument 42
do_something called with VARCHAR2 argument 05-APR-63
I don't want that third line to be allowed.
The best work-around I have so far is to create a honeypot overload that throws an application error. This catches the issue in testing but not at compile time.
DECLARE
PROCEDURE do_something(
in_ IN VARCHAR2);
PROCEDURE do_something(
in_ IN NUMBER);
PROCEDURE do_something(
in_ IN DATE);
mystery_variable_1 VARCHAR2(32767);
mystery_variable_2 NUMBER;
mystery_variable_3 DATE;
PROCEDURE do_something(
in_ IN VARCHAR2)
IS
BEGIN
dbms_output.put_line('do_something called with VARCHAR2 argument ' || in_);
END do_something;
PROCEDURE do_something(
in_ IN NUMBER)
IS
BEGIN
dbms_output.put_line('do_something called with NUMBER argument ' || in_);
END do_something;
PROCEDURE do_something(
in_ IN DATE)
IS
BEGIN
RAISE_APPLICATION_ERROR(-20001, 'do_something called with DATE argument ' || TO_CHAR(in_, 'YYYY-MM-DD HH24:MI:SS'));
END do_something;
BEGIN
mystery_variable_1 := 'Hello, World!';
mystery_variable_2 := 42;
mystery_variable_3 := TO_DATE('2063-04-05', 'YYYY-MM-DD');
do_something(mystery_variable_1);
do_something(mystery_variable_2);
do_something(mystery_variable_3);
END;
/
If I leave this work-around in place for the benefit of the maintenance developer, I get an unsightly PLW-06006
error when my private function is excluded from my package.
Can I trap this at compile time instead?
pragma deprecate
for good measure.