【问题标题】:The compiler ignores NOCOPY in these cases在这些情况下,编译器会忽略 NOCOPY
【发布时间】:2020-01-02 09:19:21
【问题描述】:

我读到了 IN OUT 和 NOCOPY。然后我遇到了 NOCOPY 用例,但我无法得到它。任何人都可以用例子解释这些吗?提前致谢。

  1. 实参必须隐式转换为形参的数据类型。

  2. 实参是集合的元素。

  3. 实际参数是一个带有NOT NULL约束的标量变量。

  4. 实际参数是一个具有范围、大小、比例或精度约束的标量数值变量。

  5. 实参和形参均为记录,其中一个或两个声明为%ROWTYPE%TYPE,对应字段的约束不同。

  6. 实参和形参都是记录,实参被(隐式)声明为游标FOR LOOP语句的索引,对应字段的约束不同。

  7. 通过数据库链接或作为外部子程序调用子程序。

【问题讨论】:

    标签: oracle plsql parameter-passing


    【解决方案1】:

    基本原则是,只要我们传递的值可以按提供的方式使用,无需转换,并且可以被调用程序寻址,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 的工作演示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      • 2016-02-25
      • 1970-01-01
      • 2017-08-30
      • 2016-06-10
      • 1970-01-01
      相关资源
      最近更新 更多