使用 Oracle PL/SQL NOCOPY 提示
参考文献:
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 提示的更多相关文章
- ORACLE PL/SQL编程详解
ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...
- [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)
原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...
- ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)
原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!) 继上篇:ORACLE P ...
- [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)
原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...
- [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)
原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...
- [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)
原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日 ...
- Oracle PL/SQL Articles
我是搬运工....http://www.oracle-base.com/articles/plsql/articles-plsql.php Oracle 8i Oracle 9i Oracle 10g ...
- ORACLE PL/SQL编程详解(转)
原帖地址:http://blog.csdn.net/chenjinping123/article/details/8737604 ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语 ...
- Oracle PL/SQL Developer 上传下载Excel
接到需求,Oracle数据库对Excel数据进行上传和下载,百度后没有很全的方案,整理搜到的资料,以备不时之需. 一.下载Oracle数据到Excel中. 下载数据到Excel在MSSql中很简单,直 ...
- [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)
原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...
随机推荐
- [转帖]HTTP X-Forwarded-For 介绍
https://www.runoob.com/w3cnote/http-x-forwarded-for.html X-Forwarded-For 是一个 HTTP 扩展头部.HTTP/1.1(RFC ...
- [转帖]005、体系结构之TiKV_Raft日志
Raft日志 1.Raft与Multi Raft 2.Raft 日志复制 2.1.复制流程总览 2.2.Propose 2.3.Append 2.3.Replicate(Append) 2.4 Com ...
- [转帖]MYSQL--表分区、查看分区
https://www.cnblogs.com/pejsidney/p/10074980.html 一. mysql分区简介 数据库分区 数据库分区是一种物理数据库设计技术.虽然分区技术可 ...
- 【转帖】eBay 云计算“网”事:网络超时篇
https://www.infoq.cn/article/JmCbkA0XX9NqrcX6loIo eBay技术荟 2020-06-19 本文字数:5508 字 阅读完需:约 18 分钟 导读 eBa ...
- [转帖] 原来awk真是神器啊
https://www.cnblogs.com/codelogs/p/16060082.html 简介# 刚开始入门awk时,觉得awk很简单,像是一个玩具,根本无法应用到工作之中,但随着对awk的了 ...
- [转帖] Linux命令拾遗-网络抓包工具
https://www.cnblogs.com/codelogs/p/16060684.html 简介# Linux中有很多抓包工具,如ngrep.tcpdump与tshark等,它们有很多用法与使用 ...
- 一个PCI-E的硬盘参数
看了下 HDD 随机 IOPS 在 100-200 之间 (读写) SATA的 SSD 随机IOPS 在 读 100k 写 20k 左右U.2的SSD 的随机IOPS 在 读 500k 写 50k 左 ...
- vue混入mixin
<div id="app"> --{{nick11}} </div> <script> // 全局混入 不需要注册 var m1 = Vue.m ...
- VS2013未能正确加载microsoft.visualstudio.editor.implementation.editorpackage
在用VS2013做项目,但是特别不顺利,这不,VS2013突然罢工了,连解决方案都打不开了,会出现如下的错误: 试了网上的各种解决方案,总算找到一个适合自己的,具体方法如下: 1.打开VS2013的& ...
- 西门子PLC高校作业以及创新项目
抢答器 在主持人按下启动按钮,3秒内