基本原则是,只要我们传递的值可以按提供的方式使用,无需转换,并且可以被调用程序寻址,PL/SQL 就会遵守 NOCOPY 指令。您列出的情况是不是这种情况的情况。我必须承认其中有几个例子让我思考,所以这是一个值得练习的练习。
前四个例子称为这个玩具过程。
create or replace procedure tst2 (p1 in out nocopy t34%rowtype) is
begin
p1.id := 42;
end;
/
案例一:实参必须隐式转换为形参的数据类型。
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:实际参数是一个带有 NOT NULL 约束的标量变量。
declare
n number not null := 23;
begin
tst(n);
dbms_output.put_line(to_char(n));
end;
/
案例 4:实际参数是具有范围、大小、比例或精度约束的标量数值变量。
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;
/
案例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;
/
下一个示例使用此包规范...
create or replace package pkg is
type r34 is record (id number, dt date);
end;
/
...和玩具程序:
create or replace procedure tst3 (p1 in out nocopy pkg.r34) is
begin
p1.id := p1.id + 10;
end;
/
案例6:实参和形参都是记录,实参被(隐式)声明为游标FOR LOOP语句的索引,对应字段的约束不同。
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;
/
有前六个案例on db<>fiddle here 的工作演示。