- 1、本文档共13页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
过程、函数、程序包涉及到的资料
使用NOCOPY编译提示传递大型数据结构
假定子程序声明了一个IN模式参数、一个OUT模式参数和一个IN OUT模式参数。在调用子程序时,IN模式的是按引用传递的,即把指向IN模式的实参指针赋给形参。所以,两个参数引用都指向同一块内存地址,这块内存存放了实参的值。
默认情况下,OUT和IN OUT模式的参数都是按值传递的。就是把实参的值拷贝到对应的形参上。然后,如果子程序正常结束,被赋到OUT和IN OUT形参上的值就会拷贝到对应的实参上。
当参数是大型数据结构时,如集合、记录和对象实例,把它们的内容全部拷贝给形参会降低执行速度,消耗大量内存。为了防止这样的情况发生,我们可以使用NOCOPY提示来让编译器按引用传递OUT和IN OUT模式的参数。在下面的例子中,我们请求编译器按引用的方式来传递IN OUT参数my_staff:
DECLARE
??TYPE?Staff?IS?VARRAY(200)?OF?Employee;
??PROCEDURE?reorganize?(my_staff?IN?OUT?NOCOPY?Staff)?IS?... 记住,NOCOPY只是一个提示,而不是指令。所以,编译器也许仍旧会把my_staff按值传递,即使我们已经发出请求了。但是,通常情况下 NOCOPY是可以成功的。下例中,我们把一个含有25000条记录的本地嵌套表中分别传递给两个没有任何功能的过程。没有使用NOCOPY的记录花费 21秒,而使用的花费不到1秒:
SQL?SET?SERVEROUTPUT?ON
SQL?GET?test.sql
1?DECLARE
2?TYPE?EmpTabTyp?IS?TABLE?OF?emp%ROWTYPE;
3?emp_tab?EmpTabTyp?:=?EmpTabTyp(NULL);?--?initialize
4?t1?NUMBER(5);
5?t2?NUMBER(5);
6?t3?NUMBER(5);
7?PROCEDURE?get_time?(t?OUT?NUMBER)?IS
8?BEGIN?SELECT?TO_CHAR(SYSDATE,SSSSS)?INTO?t?FROM?dual;?END;
9?PROCEDURE?do_nothing1?(tab?IN?OUT?EmpTabTyp)?IS
10?BEGIN?NULL;?END;
11?PROCEDURE?do_nothing2?(tab?IN?OUT?NOCOPY?EmpTabTyp)?IS
12?BEGIN?NULL;?END;
13?BEGIN
14?SELECT?*?INTO?emp_tab(1)?FROM?emp?WHERE?empno?=?7788;
15?emp_tab.EXTEND(24999,?1);?--?copy?element?1?into?2..25000
16?get_time(t1);
17?do_nothing1(emp_tab);?--?pass?IN?OUT?parameter
18?get_time(t2);
19?do_nothing2(emp_tab);?--?pass?IN?OUT?NOCOPY?parameter
20?get_time(t3);
21?dbms_output.put_line(Call?Duration?(secs));
22?dbms_output.put_line(--------------------);
23?dbms_output.put_line(Just?IN?OUT:??||?TO_CHAR(t2?-?t1));
24?dbms_output.put_line(With?NOCOPY:??||?TO_CHAR(t3?-?t2));
25*?END;
SQL?/
Call?Duration?(secs)
--------------------
Just?IN?OUT:?21
With?NOCOPY:?0 1、权衡NOCOPY所带来的良好性能
NOCOPY能为我们带来良好的性能,但它也能带来以下几个方面的影响:
因为NOCOPY只是一个提示,不是指令,所以编译器可以把NOCOPY参数按值或按引用的方式传递给子程序。所以,如果子程序因发生未捕获异常而退出时,我们就不能再信赖实参中的值了。
默认地,如果子程序异常退出,赋给OUT和IN OUT参数的值就不会拷贝到对应的实参上,这看起来有点像回滚操作。但是,对于按引用传递的NOCOPY参数来说,我们对形参所作的更改会立即在对应的实参上体现出来。所以,即使子程序是因异常发生而结束,它所做的变更内容也不会回滚。
目前,RPC协议允许我们只按值传递参数。例如,如果我们把一个
文档评论(0)