日期:2014-05-17  浏览次数:20993 次

存储过程-形参为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已经重新被赋值了;