Oracle 在这些情况下,编译器忽略NOCOPY
我读到了关于进进出出和NOCOPY的文章。然后我遇到了NOCOPY用例,但我无法得到它。有人能举例说明这些吗?提前谢谢Oracle 在这些情况下,编译器忽略NOCOPY,oracle,plsql,parameter-passing,Oracle,Plsql,Parameter Passing,我读到了关于进进出出和NOCOPY的文章。然后我遇到了NOCOPY用例,但我无法得到它。有人能举例说明这些吗?提前谢谢 实际参数必须隐式转换为形式参数的数据类型 declare n varchar2(3) := '23'; begin tst(n); dbms_output.put_line(n); end; / 实际参数是集合的元素 declare nt sys.odcinumberlist := sys.odcinumberlist(17,23,69); begin t
declare
n varchar2(3) := '23';
begin
tst(n);
dbms_output.put_line(n);
end;
/
declare
nt sys.odcinumberlist := sys.odcinumberlist(17,23,69);
begin
tst(nt(2));
dbms_output.put_line(to_char(nt(2)));
end;
/
NOT NULL
约束的标量变量declare
n number not null := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
declare
n number(5,2) := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
declare
n number not null := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
declare
n number(5,2) := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
%ROWTYPE
或%TYPE
声明的,相应字段上的约束不同declare
type r34 is record (id number, dt date);
r r34;
begin
r.id := 23;
r.dt := to_date(null); --trunc(sysdate);
tst2(r);
dbms_output.put_line(to_char(r.id));
end;
/
begin
for j in ( select * from t34) loop
tst3(j);
dbms_output.put_line(to_char(j.id));
end loop;
end;
/
declare
type r34 is record (id number, dt date);
r r34;
begin
r.id := 23;
r.dt := to_date(null); --trunc(sysdate);
tst2(r);
dbms_output.put_line(to_char(r.id));
end;
/
begin
for j in ( select * from t34) loop
tst3(j);
dbms_output.put_line(to_char(j.id));
end loop;
end;
/
declare
n number := 23;
begin
tst@remote_db(n);
dbms_output.put_line(to_char(n));
end;
/
基本原则是,只要我们传递的值可以按提供的那样使用,而不需要转换,并且可以由被调用的程序寻址,PL/SQL就会遵守NOCOPY指令。您列出的场景是情况并非如此的情况。我必须承认有几个例子让我思考,所以这是一个值得的练习 前四个例子称之为玩具程序
创建或替换程序tst2(p1 in out nocopy t34%行类型)无效
开始
p1.id:=42;
结束;
/
案例1:实际参数必须隐式转换为形式参数的数据类型
declare
n varchar2(3) := '23';
begin
tst(n);
dbms_output.put_line(n);
end;
/
案例2:实际参数是集合的元素
declare
nt sys.odcinumberlist := sys.odcinumberlist(17,23,69);
begin
tst(nt(2));
dbms_output.put_line(to_char(nt(2)));
end;
/
案例3:实际参数是带有NOTNULL约束的标量变量
declare
n number not null := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
declare
n number(5,2) := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
案例4:实际参数是具有范围、大小、比例或精度约束的标量数值变量
declare
n number not null := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
declare
n number(5,2) := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
下一个示例使用此表
create table t34 (id number not null, col1 date not null)
/
…和玩具程序:
create or replace procedure tst2 (p1 in out nocopy t34%rowtype) is
begin
p1.id := 42;
end;
/
create or replace procedure tst3 (p1 in out nocopy pkg.r34) is
begin
p1.id := p1.id + 10;
end;
/
案例5:实际参数和形式参数都是记录,其中一个或两个参数是用%ROWTYPE或%TYPE声明的,相应字段上的约束不同
declare
type r34 is record (id number, dt date);
r r34;
begin
r.id := 23;
r.dt := to_date(null); --trunc(sysdate);
tst2(r);
dbms_output.put_line(to_char(r.id));
end;
/
begin
for j in ( select * from t34) loop
tst3(j);
dbms_output.put_line(to_char(j.id));
end loop;
end;
/
下一个示例使用此包规范
create or replace package pkg is
type r34 is record (id number, dt date);
end;
/
…和玩具程序:
create or replace procedure tst2 (p1 in out nocopy t34%rowtype) is
begin
p1.id := 42;
end;
/
create or replace procedure tst3 (p1 in out nocopy pkg.r34) is
begin
p1.id := p1.id + 10;
end;
/
案例6:实际参数和形式参数是记录,实际参数被声明(隐式)为循环语句游标的索引,相应字段上的约束不同
declare
type r34 is record (id number, dt date);
r r34;
begin
r.id := 23;
r.dt := to_date(null); --trunc(sysdate);
tst2(r);
dbms_output.put_line(to_char(r.id));
end;
/
begin
for j in ( select * from t34) loop
tst3(j);
dbms_output.put_line(to_char(j.id));
end loop;
end;
/
最后一个示例使用第一个过程的远程版本
案例7:通过数据库链接或作为外部子程序调用子程序
declare
n number := 23;
begin
tst@remote_db(n);
dbms_output.put_line(to_char(n));
end;
/
有前六个案例的工作演示