存储过程-形参为out模式的传值与传引用的区别
SQL code
create or replace procedure my_proc1(temp out number)
is
begin
temp:=2;
end;
----------------------------
create or replace procedure my_proc2(temp out nocopy number)
is
begin
temp:=2;
end;
----------------------------
declare
i number:=1;
begin
dbms_output.put_line(i);
my_proc1(i);
dbms_output.put_line(i);
my_proc2(i);
dbms_output.put_line(i);
end;
输出为:
1
2
2
out模式的形参默认是传值的,声明为nocopy后就变成传引用.
这么说,应该输出为1,1,2才对呀.现在好像my_proc1与my_proc2完全没有区别了,
------解决方案--------------------默认情况下,OUT和IN OUT参数通过值传递,IN OUT的值在子程序执行前被拷贝。在子程序执行期间,会有临时变量保存输出参数的值。如果子程序正常退出,它们的值将被拷贝到实际的参数,否则原始的参数不会被改变。
当参数代表很大的结果集,如集合,记录,对象类型时,这些拷贝会比较慢并且使用很多内存。
为了避免这种性能负载,可以声明NOCOPY,允许优化器通过引用传递OUT和IN OUT参数的值。如果子程序正常退出,结果同默认的OUT/IN OUT。如果子程序非正常退出IN OUT参数的值仍然会改变。为了使用这种技术,必须确保所有的异常都被恰当处理了。
------解决方案--------------------google的,以前不知道这个nocopy,不错也算学了点
------解决方案--------------------NOCOPY的限制
需要注意,NOCOPY是一个提示,不是指示符。在以下情况下,PL/SQL不会使用NOCOPY提示,仍使用值传递:
·实际的参数是关联数组的一个元素,而不是整个关联数组。
·子程序通过数据库链接/外部过程调用;
·传递实际的参数需要隐示数据类型转换;
·实参和形参是纪录,实参声明为一个FOR循环中的一个索引,并且相应字段上的约束不同;
·实参和形参是纪录,但是其中一个或者两个都是通过%ROWTYPE或%TYPE声明,但是约束不同;
·实参有约束,如精度要求或者NOT NULL。字符除外,并且该限制不包括集合的元素和组合类型的属性。
------解决方案--------------------[Quote=引用:]
默认情况下,OUT和IN OUT参数通过值传递,IN OUT的值在子程序执行前被拷贝。在子程序执行期间,会有临时变量保存输出参数的值。如果子程序正常退出,它们的值将被拷贝到实际的参数,否则原始的参数不会被改变。
当参数代表很大的结果集,如集合,记录,对象类型时,这些拷贝会比较慢并且使用很多内存。
为了避免这种性能负载,可以声明NOCOPY,允许优化器通过引用传递OUT和IN OUT参数的值。如果子程序正常退…
[/Quote]
学习了,支持!nocopy工作中用到的地方很少!
------解决方案--------------------nocopy没有用过;
但我觉得输出的结果是没有什么问题的;
很明显的,temp已经重新被赋值了;