When invoking a PL/SQL procedure or function, you can specify the value of its parameters using either positional, named, or mixed notation. Let’s review what each notation means and then demonstrate the best way to add new parameters to an existing subprogram without breaking existing code.
Consider this simple package as an example:
CREATE OR REPLACE PACKAGE ed_test_pkg
AS
PROCEDURE proc1 (
param1_in IN NUMBER,
param2_in IN NUMBER,
param1_out OUT NUMBER
);
END ed_test_pkg;
/
CREATE OR REPLACE PACKAGE BODY ed_test_pkg
AS
PROCEDURE proc1 (
param1_in IN NUMBER,
param2_in IN NUMBER,
param1_out OUT NUMBER
)
AS
BEGIN
param1_out := param1_in + param2_in;
END proc1;
END ed_test_pkg;
/
Positional Notation:
When you invoke a procedure using positional notation, you specify the parameters in the same order as the procedure declares them. For example:
DECLARE
l_param1_out NUMBER;
BEGIN
ed_test_pkg.proc1 (1, 2, l_param1_out);
DBMS_OUTPUT.put_line ('l_param1_out = ' || l_param1_out);
END;
Named Notation:
When you invoke a procedure using named notation, you specify the name and value of each parameter, using the association operator =>. The order of parameters is irrelevant. For example:
DECLARE
l_param1_out NUMBER;
BEGIN
ed_test_pkg.proc1 (param2_in => 2,
param1_out => l_param1_out,
param1_in => 1
);
DBMS_OUTPUT.put_line ('l_param1_out = ' || l_param1_out);
END;
Mixed Notation:
When you invoke a procedure using mixed notation, you start with positional notation, then use named notation for the remaining parameters. For example:
DECLARE
l_param1_out NUMBER;
BEGIN
ed_test_pkg.proc1 (1, param2_in => 2, param1_out => l_param1_out);
DBMS_OUTPUT.put_line ('param1_out = ' || l_param1_out);
END;
Which one to use?
After this quick notations refresher, the question is which one to choose as your preferred style when invoking PL/SQL programs? For me, I prefer, and almost always use, the named notation, and you should too. OK, I admit there is more typing involved in named notation, but it is easier to read and maintain than the other two. Moreover, if the program’s parameter list changes, you avoid changing the code that invokes the program using named notation.
Adding a new parameter
Speaking of changing the parameter list, let’s say you have to add a new param3_in IN parameter to the procedure ed_test_pkg.proc1. Which one of the following two approaches do you use?
Approach 1:
PROCEDURE proc1 (
param1_in IN NUMBER,
param2_in IN NUMBER,
param3_in IN NUMBER DEFAULT 1,
param1_out OUT NUMBER
);
Approach 2:
PROCEDURE proc1 (
param1_in IN NUMBER,
param2_in IN NUMBER,
param1_out OUT NUMBER,
param3_in IN NUMBER DEFAULT 1
);
As you know, adding DEFAULT to the IN parameter means that you do not have to pass in a value to this parameter, and if you don’t provide a value, the default value is used.
Now, you may be tempted to keep all the IN parameters together, however, the second approach is better. Adding the parameter to the end of the parameter list is safer. Let me show you why.
Let’s say you have a program that calls ed_test_pkg.proc1 using the positional notation. When you add a new IN parameter using the first approach, and if you do not make any further modifications to the code, you’ll get an error:
SQL> DECLARE
2 l_param1_out NUMBER;
3 BEGIN
4 ed_test_pkg.proc1 (1, 2, l_param1_out);
5 DBMS_OUTPUT.put_line ('l_param1_out = ' || l_param1_out);
6 END;
7 /
ed_test_pkg.proc1 (1, 2, l_param1_out);
*
ERROR at line 4:
ORA-06550: line 4, column 4:
PLS-00306: wrong number or types of arguments in call to 'PROC1'
ORA-06550: line 4, column 4:
PL/SQL: Statement ignored
But, you will not get this error if you use approach 2 or if you use the named notation when calling ed_test_pkg.proc1.
Conclusion
So, in general, as a best practice, always use named notation when invoking PL/SQL procedures and functions. To avoid breaking existing code, add new parameters with DEFAULT values to the end of the parameter list of existing procedures or functions.
Source and Resources:
- Adding IN parameter
- Using Positional, Named, or Mixed Notation for PL/SQL Subprogram Parameters
- 11g New Features: Efficient PL/SQL Coding
Possibly related:
- Simple Tips to Quickly Find Answers to Your Oracle-Related Questions and Keep Your Oracle Skills Up to Date
- A Quick Update
- links for 2006-08-18
- Oracle PLSQL in CFQUERY
- Did You Know That About PL/SQL Variables?
Tagged parameter, pl/sql | Post a Comment | Trackback URI


















“So, in general, as a best practice, always use named notation when invoking PL/SQL procedures and functions. To avoid breaking existing code, add new parameters with DEFAULT values to the end of the parameter list of existing procedures or functions.”
Wouldn’t overloading the routine accomplish the same goal?
February 28th, 2008, at 10:09 am #Hi Brian,
using named notation is the best approach to invoking a subprogram, whether you overload or not. But, yes, if the goal is not to break existing code when adding new parameters, overloading the routine can accomplish this goal. Thanks for point this out.
February 28th, 2008, at 10:49 am #Eddie, what do you think about the fact that in function calls named notation (to 10g, i don’t know 11g) is not supported?
I think that overload may be a good solution but it depends of what do you have to do with the new parameter.
Cheers,
February 28th, 2008, at 12:08 pm #Cristian
Hi Cristian,
I believe that named notation is not supported in 10g (and earlier releases) only when you call a function inside a SELECT statement. However, in 11g, this has been fixed.
Check out the link titled “11g New Features: Efficient PL/SQL Coding” in the post above. There is more information about this towards the end of the page.
February 28th, 2008, at 12:36 pm #Hi Eddie
Not sure I agree with you on this one in all cases and you hint that you nearly always use named notation, implying there are cases when you use positional notation. In particular I’ll point out 2 cases where positional notation is typically used:
1) Oracle has a number of predefined functions that we rarely ever use named parameter notation for. eg upper, lower etc.
2) If you have a simple function with 1 parameter such as get_name(id IN person.id%TYPE), the code is self explanatory without the named notation extension and I think overkill for simple cases:
DECLARE
person_id person.id%TYPE := 5;
name person.name%TYPE;
BEGIN
name := somepackage.get_name(person_id);
END;
Besides these trivial cases, I agree with the rest of your points. Now you need a post on writing “meaningful parameter names”
Regards,
CM.
February 28th, 2008, at 5:22 pm #Valid points Chris, especially on writing meaningful parameter names, not to mention meaningful variables names, procedure names, function names, package names….
Maybe I should not have put “in general”, “best practice” and “always” in the same sentence
February 28th, 2008, at 5:44 pm #Hi,
I fully agree with Chris. I really like name notation and I use it often, but not always.
When I use standard Oracle build in functions or for well established API (mine, 3rd party, or specific to project) with limited number of parameters (usually up to 3 or 4) I rather use positional notation.
And of course within SQL statements, where named parameters are not allowed (hope I will work on 11g soon)
Regards,
March 1st, 2008, at 2:10 am #Pawel
By the way, as you’ve noticed from the example code above, I also like to add _in to the end of IN parameter names, _out for OUT parameters and _inout for IN OUT. This makes the named notation even more readable.
March 1st, 2008, at 11:20 am #