Skip to Main Content
  • Questions
  • Can a function automatically return NULL when the only parameter to it is passed as NULL?

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Maaz.

Asked: October 23, 2009 - 9:31 am UTC

Last updated: October 26, 2009 - 3:18 pm UTC

Version: 10.2.0.4

Viewed 10K+ times! This question is

You Asked

Dear Tom,

One of my developers asked me a very interesting question today; If we have a procedure as such (Please excuse the use of the DUAL table, I couldn't think of a better one):

FUNCTION foo (p_parameter_i IN dual.dummy%TYPE;)
   RETURN VARCHAR2
IS
   CURSOR v_Cur
   IS
      SELECT 'Y'
        FROM dual a
       WHERE a.dummy = p_parameter_i;

   v_ReturnMe dual.dummy%TYPE;
BEGIN
   OPEN v_Cur;
   FETCH v_Cur INTO v_ReturnMe;
   CLOSE v_Cur;
   
   RETURN v_ReturnMe;
END;


If the code is invoked by passing a NULL value for p_parameter_i, the PLSQL engine will evaluate the SQL unnecessarily because the result will be NULL.

To go around it, one would have to create the procedure as:

FUNCTION foo (p_parameter_i IN dual.dummy%TYPE;)
   RETURN VARCHAR2
IS
   CURSOR v_Cur
   IS
      SELECT 'Y'
        FROM dual a
       WHERE a.dummy = p_parameter_i;

   v_ReturnMe dual.dummy%TYPE;
BEGIN
   IF p_parameter_i IS NULL
   THEN 
      RETURN;
   END IF;

   OPEN v_Cur;
   FETCH v_Cur INTO v_ReturnMe;
   CLOSE v_Cur;
   
   RETURN v_ReturnMe;
END;


Is there a way to create a function as one that will return NULL automatically when its only parameters value is NULL?

PS. I have researched Oracle Docs and haven't found anything in reference to this question.

and Tom said...

you have found the way to make something like that happen.


by the way, you have a bug in your code. two of them at at least.


a) you do not verify you actually FETCHED ANYTHING.
b) you do not verify that there is only ONE VALUE TO BE FETCHED


that procedure should be:
begin
   if (parm is null) then return; end if;
   select 'y' into v_returnme from dual where dummy = parm;
   return v_returnme;
end


never ever use the open/fetch/close - you would have to code:

open c
fetch c
if c%notfound then error
fetch c
if c%found then error
close c


to do it correctly, select into does it correctly (fewer bugs in your code that way) and faster than open/fetch/close does.



Rating

  (4 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

As informative as possible :)

Maaz Anjum, October 26, 2009 - 10:40 am UTC

Ah, I was typing away without realizing that I had a bug in the code but thank you for pointing it out!

I thought at some point explicit cursors were more efficient than implicit ones but after the latter releases (after 8i), it made no difference so I kept with the earlier.

Thanks again for the helpful information!!
Tom Kyte
October 26, 2009 - 2:30 pm UTC

... I thought at some point explicit cursors were more efficient than implicit ones
...

that MIGHT have been true sometime in the late 1980's (that is not a typo, that is 1980's) with really old releases of Forms.

but otherwise, in plsql code - no, it was never true.

RE: implicit vs explicit cursors

Duke Ganote, October 26, 2009 - 10:47 am UTC

As Tom has noted before, implicit cursors are generally faster to code and have better performance:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1205168148688

PLS-00503

Sokrates, October 26, 2009 - 11:58 am UTC

...
IF p_parameter_i IS NULL
THEN
RETURN;
END IF;
...

wouldn't compile

PLS-00503: RETURN <value> statement required for this return from function

Tom Kyte
October 26, 2009 - 3:18 pm UTC

so, what do you want to return... seems like an obvious fix?

Maaz Anjum, October 26, 2009 - 12:28 pm UTC

Silly typo, thanks for the correction!

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library