Oracle12C--NOCOPY选项(四十三)

来源:互联网 发布:王欣认罪 知乎 编辑:程序博客网 时间:2024/05/19 22:25

知识点的梳理:

  • IN参数类型无法使用NOCOPY选项

      

  • NOCOPY选项的意义
    • 默认,IN模式传递参数采用引用传递方式;而OUTIN OUT采用数值传递,传递时,会将数据复制一份给形参;而在过程结束之后,被赋予OUTIN OUT形参上的值会复制回对应的实参;
    • 由于OUT,IN OUT的操作会进行复制,当数据较大时,复制的过程会变慢,且消耗大量内存;
    • 在定义过程参数时,可以使用NOCOPY选项,将值传递变为引用传递;
    • 定义语法:

参数名称 [参数模式] NOCOPY数据类型;

  • 举个栗子
    • 示例1:使用NOCOPY定义过程参数

DECLARE

TYPE dept_nested IS TABLE OF dept%ROWTYPE ;

v_dept dept_nested ;

PROCEDURE useNocopy_proc(p_temp IN OUT NOCOPY dept_nested)

IS

BEGIN

--相关程序代码

END ;

BEGIN

SELECT * BULK COLLECT INTO v_dept FROM dept ; --将雇员表全部数据拷贝到嵌套表之中

v_dept.EXTEND(2000000,1) ; --将集合扩充,数据以第1条记录为准进行填充

useNocopy_proc(v_dept) ; --使用NOCOPY

END ;

/

分析:
此程序只是一个
NOCOPY定义的示例;
可以在程序主体部分传递一个包含多个参数的数据集合

  • NOCOPY定义的参数,即使程序出现了错误,也可以正常的返回
    • 示例1:使用NOCOPY选项 —— 即使出现错误,NOCOPY也可以自动处理

DECLARE

v_varA NUMBER := 10 ;

v_varB NUMBER := 20 ;

PROCEDURE change_proc(

p_paramINOUT IN OUT NUMBER ,

p_paramNOCOPY IN OUT NOCOPY NUMBER)

IS

BEGIN

p_paramINOUT := 100 ;

p_paramNOCOPY := 100 ;

RAISE_APPLICATION_ERROR(-20001 , '测试NOCOPY.') ;

END ;

BEGIN

DBMS_OUTPUT.put_line('【过程调用之前】v_varA = ' || v_varA || 'v_varB = ' || v_varB) ;

BEGIN

change_proc(v_varA , v_varB) ;

EXCEPTION

WHEN OTHERS THEN

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE || 'SQLERRM = ' || SQLERRM) ;

END ;

DBMS_OUTPUT.put_line('【过程调用之后】v_varA = ' || v_varA || 'v_varB = ' || v_varB) ;

END ;

/

运行结果:

【过程调用之前】v_varA = 10,v_varB = 20

SQLCODE = -20001,SQLERRM = ORA-20001: 测试NOCOPY.

【过程调用之后】v_varA = 10,v_varB = 100

分析:
本程序定义的过程接收了两个参数,此过程会修改它们的内容,并将它们的内容返回到相应的变量上。但是由于此时过程抛出了一个异常,所以最终只有
NOCOPY定义的参数将结果返回了;没有使用此选项的参数不能正常返回

  • 示例2:不使用NOCOPY选项

DECLARE

v_varA NUMBER := 10 ;

v_varB NUMBER := 20 ;

PROCEDURE change_proc(

p_paramINOUT IN OUT NUMBER ,

p_paramNOCOPY IN OUT NOCOPY NUMBER)

IS

BEGIN

p_paramINOUT := 100 ;

p_paramNOCOPY := 100 ;

END ;

BEGIN

DBMS_OUTPUT.put_line('【过程调用之前】v_varA = ' || v_varA || 'v_varB = ' || v_varB) ;

change_proc(v_varA , v_varB) ;

DBMS_OUTPUT.put_line('【过程调用之后】v_varA = ' || v_varA || 'v_varB = ' || v_varB) ;

END ;

/

运行结果:

【过程调用之前】v_varA = 10,v_varB = 20

【过程调用之后】v_varA = 100,v_varB = 100