为了更好地理解,让我们回顾PL/SQL如何以两种方式处理参数:
通过引用
在这种情况下,指向实际参数的指针被传递给相应的形式参数.实际和形式参数都指向内存中保存参数值的相同位置.
按值
在这种情况下,实际参数的值将复制到相应的形式参数.如果程序随后终止而没有异常,则将形式参数值复制回实际参数.如果发生错误,则更改的值不会复制回实际参数.
默认情况下,OUT和IN OUT参数按值传递,IN参数通过引用传递.在过程内部修改OUT或IN OUT参数时,过程实际上只修改参数值的副本.仅当过程完成且无异常时,结果值才会复制回形式参数.
procedure add_numbers(
first_val in number,
second_val in out number
)
BEGIN
second_val := first_val + second_val;
--some other statements
END;
/
Run Code Online (Sandbox Code Playgroud)
测试:
BEGIN
par_in = 124;
par_inout = 76;
add_numbers(par_in, par_inout);
DBMS_OUTPUT.PUT_LINE(par_inout);
END;
/
Run Code Online (Sandbox Code Playgroud)
上面的例子将200
在屏幕上打印出来.传递给add_numbers
过程的参数有两个:
par_in
模式IN
.此参数通过引用传递.因此,在add_numbers
过程中,不会创建此参数的其他副本.相反,将使用相同的副本.如果允许您修改过程first_val
内的值add_numbers
(但您不是),则该值将直接反映到par_in
.因为只是两个first_val
并且par_in
是同一个内存位置的两个名称.par_inout
模式IN OUT
.默认情况下,此参数按值传递.因此,在add_numbers
过程中,将分配新的(内存位置)来存储该参数的另一个副本.因此,par_inout
是内存中不同位置的名称second_val
.他们两个名字到两个不同的位置.第二个参数的含义是,在second_val := first_val + second_val;
执行该行之后,该值与该过程结束之前的second_val
值不同par_inout
.仅在过程结束时,second_val
将传递给的值par_inout
.
现在,如果将大型集合作为OUT或IN OUT参数传递,则它将按值传递,换句话说,整个集合将在进入过程时复制到形式参数,并在退出过程时再次复制.如果集合很大,则会导致不必要的CPU和内存消耗.
该NOCOPY参数模式提示可以解决这个问题,因为你可以用它来指导运行时引擎,试图通过引用而不是通过值OUT或IN OUT参数传递
提示请求PL/SQL运行时引擎通过引用而不是值传递IN OUT参数.这可以加快程序的性能,因为不会在程序单元中复制引用参数.当您传递大型复杂结构(如集合,记录或对象)时,此复制步骤可能会很昂贵.