参考文献:

      official document: http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/tuning.htm#LNPLS01208

      oracle nocopy hint tips: http://www.dba-oracle.com/plsql/t_plsql_nocopy_hint.htm

                                             http://www.dba-oracle.com/t_pl_sql_nocopy_data_structures.htm

一 概念介绍

PLSQL运行引擎在存储过程和函数之间传参有2种方法:传值和传引用

默认情况,OUT和IN OUT参数通过传值方式传递,IN参数是传引用方式。程序执行前IN OUT参数的实际值将被复制给形参。程序执行中间,临时变量保存参数的输出值。如果程序正常退出,这些值将被复制回原参数。如果程序异常退出,那么原参数值将不会改变。当IN OUT参数为大数据结构,诸如:集合、记录、对象类型实例时,通过传值方式的COPY动作将会导致程序执行速度下降,使用内存量上升。尤其是该程序被多次调用时更是如此。

为避免此类情况,我们可以指定NOCOPY暗示,告诉PLSQL编译器通过传引用方式传递OUT 和IN OUT参数。这样,形参将不会COPY参数实际值,也就是说形参和ACTUAL VALUE指向同一内存地址(memory location)。以此提高程序执行性能。

下面通过一段脚本对比一下,传值和传引用在程序执行性能上的差异:

二 示例对比:

nocopy.sql

SET SERVEROUTPUT ON
DECLARE
TYPE t_tab IS TABLE OF VARCHAR2(32767);
l_tab t_tab := t_tab();
l_start NUMBER; PROCEDURE in_out (p_tab IN OUT t_tab) IS
BEGIN
NULL;
END; PROCEDURE in_out_nocopy (p_tab IN OUT NOCOPY t_tab) IS
BEGIN
NULL;
END;
BEGIN
l_tab.extend;
l_tab(1) := '1234567890123456789012345678901234567890';
l_tab.extend(999999, 1); -- Copy element 1 into 2..1000000 -- Time normal IN OUT
l_start := DBMS_UTILITY.get_time; in_out(l_tab); DBMS_OUTPUT.put_line('IN OUT : ' ||
(DBMS_UTILITY.get_time - l_start)); -- Time IN OUT NOCOPY
l_start := DBMS_UTILITY.get_time; in_out_nocopy(l_tab); -- pass IN OUT NOCOPY parameter DBMS_OUTPUT.put_line('IN OUT NOCOPY: ' ||
(DBMS_UTILITY.get_time - l_start));
END;
/

SQL> @nocopy.sql

IN OUT       :43
IN OUT NOCOPY: 0

PL/SQL procedure successfully completed.

三 使用NOCOPY限制:

1、如果实参为整个关联数组则该限制不起作用。
2、实参被强制指定精度,比例或not null时,该限制将不适用按最大长度强制的字符串参数。
3、实参和形参都是记录类型,二者存在以隐式方式或使用了%ROWTYPE类型声明时,作用在对应字段的强制说明不一制。
4、传递实参需要隐式类型转换时。
5、子程序涉及到远程调用(RPC---database link oras an external procedure)。

四 关于使用NOCOPY过程中的异常处理

虽说NOCOPY带来了性能上的优势,但是不容忽略的一点是当我们调用的子程序(带有NOCOPY提示)发生异常时,一旦处理不当很容易造成实参被修改。这是我们不愿看到的。下面引用官方的一段话并结合newkid大师的例子给予说明,详细请见ITPUB版:

   http://www.itpub.net/thread-1147041-1-1.html

   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 p_nocopy_test(p_id OUT NOCOPY NUMBER)
AS
BEGIN
p_id := 1;
raise_application_error(-20201,'NULL'); --程序终止
p_id := 2; RETURN;
END;
/ DECLARE
v_id NUMBER := 0;
BEGIN
dbms_output.put_line('Before call p_nocopy_test: '||v_id);
p_nocopy_test(v_id);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('After call p_nocopy_test: '||v_id); END;
/

Before call p_nocopy_test: 0
After call p_nocopy_test: 1

再来看一下去掉NOCOPY参数的子程序调用在遇到异常时的表现:

Before call p_nocopy_test: 0
After call p_nocopy_test: 0

那么针对NOCOPY子程序的异常处理该如何做?Oracle前面说了应该在子程序内部捕捉处理掉异常,例如:

CREATE OR REPLACE PROCEDURE p_nocopy_test(p_id OUT NOCOPY NUMBER)
AS
BEGIN
p_id := 1;
raise_application_error(-20201,'NULL'); --程序终止
p_id := 2; --RETURN;
EXCEPTION
WHEN OTHERS THEN
p_id := 0;
RETURN;
END;
/ DECLARE
v_id NUMBER := 0;
BEGIN
dbms_output.put_line('Before call p_nocopy_test: '||v_id);
p_nocopy_test(v_id);
/*
EXCEPTION
WHEN OTHERS THEN
*/
dbms_output.put_line('After call p_nocopy_test: '||v_id); END;
/

Before call p_nocopy_test: 0


After call p_nocopy_test: 0

-------------------

Dylan presents.

  

使用 Oracle PL/SQL NOCOPY 提示的更多相关文章

  1. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  2. [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

    原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...

  3. ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)

    原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!)   继上篇:ORACLE P ...

  4. [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

    原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...

  5. [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)

    原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...

  6. [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

    原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日 ...

  7. Oracle PL/SQL Articles

    我是搬运工....http://www.oracle-base.com/articles/plsql/articles-plsql.php Oracle 8i Oracle 9i Oracle 10g ...

  8. ORACLE PL/SQL编程详解(转)

    原帖地址:http://blog.csdn.net/chenjinping123/article/details/8737604 ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语 ...

  9. Oracle PL/SQL Developer 上传下载Excel

    接到需求,Oracle数据库对Excel数据进行上传和下载,百度后没有很全的方案,整理搜到的资料,以备不时之需. 一.下载Oracle数据到Excel中. 下载数据到Excel在MSSql中很简单,直 ...

  10. [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)

    原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...

随机推荐

  1. Go-选择排序

    // SelectionSort 选择排序 // 思路: // 1. 遍历整个元素集合,将最小值取出追加到一个有序的元组 // 2. 重复遍历剩余元素集合,取出最小值追加到一个有序元组 // 选择排序 ...

  2. Chrome显示和更改显示网页字符集的方法

    Chrome显示和更改显示网页字符集的方法 背景 前段时间学习和总结了unicode和utf8的一些知识. 当时想到应该学习和整理一下网站网页的编码格式字符集相关的内容 想着既然给自己立了flag, ...

  3. [转帖]通过 TiUP 部署 TiDB 集群的拓扑文件配置

    https://docs.pingcap.com/zh/tidb/stable/tiup-cluster-topology-reference 通过 TiUP 部署或扩容 TiDB 集群时,需要提供一 ...

  4. [转帖]Linux:CPU频率调节模式以及降频方法简介

    概述 cpufreq的核心功能,是通过调整CPU的电压和频率,来兼顾系统的性能和功耗.在不需要高性能时,降低电压和频率,以降低功耗:在需要高性能时,提高电压和频率,以提高性能. cpufreq 是一个 ...

  5. 【转帖】eBay 云计算“网”事|网络重传篇

    https://www.infoq.cn/article/iy1drmf6wk8up14dchq8/ #导读 在之前的eBay云计算"网"事|网络超时篇和eBay云计算" ...

  6. 【图论,网络流】CF1525F Goblins And Gnomes

    Problem Link 你在打怪.你有一个 \(n\) 个点 \(m\) 条边的 DAG,接下来会有 \(k\) 波怪来袭,第 \(i\) 波怪有 \(i\) 个,它们会各自选择走一条路径,要求它们 ...

  7. git提交出现running pre-commit hook: lint-staged

    现象 今天提交代码的时候出现了 > running pre-commit hook: lint-staged Stashing changes... [started] Stashing cha ...

  8. TypeScript枚举类型

    枚举 简单理解就是将所有的情况列举出来. 枚举不是用来定义类型的哈.就是说枚举不是一种数据类型. enum xxx={ key1=value1, key2=value2, } 通过 xxx.key1的 ...

  9. ts函数讲解与不确定参数是否使用以及限制返回类型

    1.声明式函数 函数有两个参数 参数的数据类型是 string number 返回值值 number 哈 function person(name: string, age: number): num ...

  10. Typora 1.6.7永久激活

    介绍Typora介绍 具体看上面的我就不多介绍了 接下来我们开始教程 需要的文件 Typora安装包 破解补丁包 安装包下载 破解补丁下载 接下来我们全部下载后获得一个安装包一个补丁 安装包直接安装就 ...