我在网上看到,发现程序中的IN参数是通过引用传递的。你能用一个例子解释一下吗?提前谢谢。
答案 0 :(得分:9)
为了更好地理解,让我们回顾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;
/
TEST:
BEGIN
par_in = 124;
par_inout = 76;
add_numbers(par_in, par_inout);
DBMS_OUTPUT.PUT_LINE(par_inout);
END;
/
上面的示例将在屏幕上打印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 Parameter Mode Hint缓解了这个问题,因为您可以使用它来指示运行时引擎尝试通过引用而不是按值传递OUT或IN OUT参数
提示请求PL / SQL运行时引擎通过引用而不是值传递IN OUT参数。这可以加快程序的性能,因为不会在程序单元中复制引用参数。当您传递大型复杂结构(如集合,记录或对象)时,此复制步骤可能很昂贵。