Professional Documents
Culture Documents
Call by Reference Parameters in PL
Call by Reference Parameters in PL
For example:
To get around this, package variables were being used to pass values around.
Though serviceable as an alternative to prevent multiple buffers and copy
overhead, it resulted in higher maintenance cost.
From Oracle 8i onwards, the NOCOPY parameter hint has been introduced for
OUT and IN OUT parameters. Using this hint tells Oracle to make a call by
reference. Use this hint when there is no need to preserve the original value (in
case the called routine raises an exception). Oracle's internal benchmark testing
shows improvements of 30% to 200% for PL/SQL tables being passed as
parameters. NOCOPY is the ideal hint for OUT and IN OUT parameters when
the original value is not to be preserved (as is generally the case).
Here's an example:
Drawbacks
NOCOPY is a hint and Oracle does not guarantee a parameter will be passed by
reference when explicitly mentioned. Here are some places where this is not
possible:
There may be other situations where Oracle may decide a call by value over a
call by reference. Since this is not clearly specified, it is advisable not to build any
process logic on this feature when exceptions being raised in the called routine
are being trapped in the calling routine.
The PL/SQL runtime engine has two different methods for passing parameter values
between stored procedures and functions, by value and by reference.
When a parameter is passed by value the PL/SQL runtime engine copies the actual value
of the parameter into the formal parameter. Any changes made to the parameter inside the
procedure has no effect on the values of the variables that were passed to the procedure
from outside.
When a parameter is passed by reference the runtime engine sets up the procedure call so
that both the actual and the formal parameters point (reference) the same memory
location that holds the value of the parameter.
By default OUT and IN OUT parameters are passed by value and IN parameters are
passed by reference. When an OUT or IN OUT parameter is modified inside the
procedure the procedure actually only modifies a copy of the parameter value. Only when
the procedure has finished without exception is the result value copied back to the formal
parameter.
Now, if you pass a large collection as an OUT or an IN OUT parameter then it will be
passed by value, in other words the entire collection will be copied to the formal
parameter when entering the procedure and back again when exiting the procedure. If the
collection is large this can lead to unnecessary CPU and memory consumption.
The NOCOPY hint alleviates this problem because you can use it to instruct the runtime
engine to try to pass OUT or IN OUT parameters by reference instead of by value. For
example:
procedure get_customer_orders(
p_customer_id in number,
p_orders out nocopy orders_coll
);
theorders orders_coll;
get_customer_orders(124, theorders);
In the absence of the NOCOPY hint the entire orders collection would have been copied
into the theorders variable upon exit from the procedure. Instead the collection is now
passed by reference.
Keep in mind, however, that there is a downside to using NOCOPY. When you pass
parameters to a procedure by reference then any modifications you perform on the
parameters inside the procedure is done on the same memory location as the actual
parameter, so the modifications are visible. In other words, there is no way to “undo” or
“rollback” these modifications, even when an exception is raised midway. So if an
exception is raised inside the procedure the value of the parameter is “undefined” and
cannot be trusted.
To sum up, a NOCOPY hint can offer a small performance boost, but you must be careful
and know how it affects program behavior, in particular exception handling.