重庆思庄Oracle、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3417|回复: 0
打印 上一主题 下一主题

oracle之nocopy关键词

[复制链接]
跳转到指定楼层
楼主
发表于 2014-4-2 11:53:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

PL/SQL中对out,in out参数使用的?默认形参会复制一份实参的副本,然后在内部传递,修改等,发生异常,不会赋值给实参,控制权交还调用环境,而实参值不变,还是调用前的值。而使用了NOCOPY后,形参将获得一个指向实参的指针,然后在内部传递,赋值都直接修改实参了,此时如果异常发生,控制权交还调用环境,但是实参已经被修改了。无法还原成调用前的值。
    对参数I N使用NOCOPY将会产生编译错误,这是因为参数I N总是按引用传递.
     NOCOPY的主要优点是可以提高程序的效率。当我们传递大型PL/SQL表时,其优越性特别显著.使用NOCOPY的限制在某些情况下,NOCOPY将被编译器忽略,这时的参数仍将按值传递。这时,编译器不会报告编译错误。由于NOCOPY是一个提示项(Hint),编译器可以决定是否执行该项。在下列情况下,编译器将忽略NOCOPY项:
1.实参是索引表(index-by table)的成员时。如果该实参是全表,则该限制不起作用。
2.实参被强制指定精度,比例或NOT NULL时。该限制将不适用按最大长度强制的字符串参数。
3.实参和形参都是记录类型,二者是以隐含方式或使用了%ROWTYPE类型声明时,作用在对应字段的强制说明不一致。
4.传递实参需要隐式类型转换时。
5.子程序涉及到远程过程调用(PRC)。远程过程调用就是跨越数据库对远程服务器的过程调用。


If the subprogram exits early with an exception, the values of OUT and IN OUT parameters (or object attributes) might still change. To use this technique, ensure that the subprogram handles all exceptions.

 

CREATE OR REPLACE PROCEDURE SP_TEST (P_OUT OUT NOCOPY NUMBER)
AS
BEGIN
   P_OUT :=1;
   RAISE_APPLICATION_ERROR(-20001,'ERROR');
   P_OUT :=2;
   RETURN;
END;
/


DECLARE
   V_OUT NUMBER :=0;
BEGIN
   DBMS_OUTPUT.PUT_LINE('BEFORE CALLING SP_TEST: V_OUT = '||V_OUT);
   SP_TEST(V_OUT);
EXCEPTION
   WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('AFTER CALLING SP_TEST: V_OUT = '||V_OUT);
END;
/

使用了nocopy之后,如果在被调用过程中没有很好的异常处理机制,会导致out参数返回的值产生不确定性,反而会影响程序结果的正确性。所以有些场景还是不使用nocopy为好。

 

输出:
BEFORE CALLING SP_TEST: V_OUT = 0
AFTER CALLING SP_TEST: V_OUT = 1

去掉NOCOPY的输出:
BEFORE CALLING SP_TEST: V_OUT = 0
AFTER CALLING SP_TEST: V_OUT = 0

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2024-7-5 14:40 , Processed in 0.096078 second(s), 21 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表