【问题标题】:PLS-00201 – identifier must be declared, passing a collection to procedurePLS-00201 – 必须声明标识符,将集合传递给过程
【发布时间】:2021-02-11 20:19:40
【问题描述】:

我正在尝试将集合传递给过程,但是当我编译包时,我会收到以下消息:“PLS-00201 – 必须声明标识符”。 这是我的代码:

create or replace package PACK_DW_TEMP  
as

procedure A (.......);
--
procedure B (error_list in out l_error);

end PACK_DW_TEMP; 

在包体中,我在过程 A 中创建了集合并将其传递给过程 B

create or replace package body PACK_DW_TEMP
as

procedure A ( ........ )
as
begin
declare

     
    
    type error IS RECORD(
            cod_error       NUMBER,
            descr_error     VARCHAR2(100)
            );

    type l_errori is table of error;
    error_list  l_error := l_error(); 
begin
  procedure B(error_list);
end;
end;

进入程序B:

procedure B ( error_list in out l_error )
as
begin
declare
    i    NUMBER;
    
    type err IS RECORD(
            cod_error       NUMBER,
            descr_error     VARCHAR2(100)
            );

    type l_err is table of err;
    err_list  l_err := l_err(); 

begin
     i := 0;
     for i in 1..5 loop
      err_list(i).cod_err := error_list(i).cod_error;
      err_list(i).descr_err := error_list(i).descr_error;
     end loop;
end;

end;    

我的目标是将集合传递给过程 B 并将值分配给新集合。

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    一个在本地声明给一个过程的类型和另一个在本地声明给另一个过程的类型完全是不同的类型,你不能将一个传递给另一个。您需要在过程外部而不是内部创建类型。

    此外,如果没有声明包的签名中的类型,除了在包主体中声明的过程的内部之外,您不能使用该类型。

    create or replace package PACK_DW_TEMP  
    as
      TYPE error IS RECORD(
        cod_error       NUMBER,
        descr_error     VARCHAR2(100)
      );
    
      type l_error is table of error;
      procedure A;
      procedure B (error_list in out l_error);
      
    end PACK_DW_TEMP;
    /
    

    create or replace package body PACK_DW_TEMP
    as
      procedure A
      as
        error_list  l_error := l_error(); 
      begin
        error_list.EXTEND(2);
        error_list(1).cod_error   := 1;
        error_list(1).descr_error := 'DESCR1';
        error_list(2).cod_error   := 2;
        error_list(2).descr_error := 'DESCR2';
        
        B(error_list);
    
        FOR i IN 1 .. error_list.COUNT LOOP
          DBMS_OUTPUT.PUT_LINE(
            error_list(i).cod_error || ': ' || error_list(i).descr_error
          );
        END LOOP;
      end;
    
      procedure B ( error_list in out l_error )
      as
      begin
        error_list.EXTEND;
        error_list(error_list.COUNT).cod_error   := 99;
        error_list(error_list.COUNT).descr_error := 'DESCR99';
      end;
    end;    
    /
    

    然后你可以调用它:

    BEGIN
      PACK_DW_TEMP.A();
    END;
    /
    

    哪些输出:

    1: DESCR1
    2: DESCR2
    99: DESCR99
    

    db小提琴here

    【讨论】:

    • 谢谢...我写这个是因为,我也必须将集合的价值添加到过程 B 中。所以我必须将集合从 A 传递到 B,从 B 传递到 A。在迭代结束时,我将打印集合中的值。我可以更改您的示例,而不是显示值,而是以与过程 A 相同的方式将值添加到集合中。对吗?
    • 感谢您的解决方案。我正在测试你的解决方案。一个问题:error_list.count 给出了集合中元素的数量。如何增加集合的索引?error_list.EXTEND 会这样做吗?
    • @Scripta14 Oracle documentation for collection methods is here。 [TL;DR] 是的,collection.COUNT 给出了集合的当前最大大小,是的,collection.EXTEND(int) 增加了集合的最大大小。
    • 感谢您的解决方案并回复我。
    【解决方案2】:

    您在包体中定义了一个名为l_err 的类型,但在过程B 中您尝试使用一个名为l_error 的类型。此外,在第一次使用之前,您必须在包规范中定义 l_error

    create or replace package PACK_DW_TEMP  
    as
      type err IS RECORD(
              cod_error       NUMBER,
              descr_error     VARCHAR2(100)
              );
    
      type l_error is table of err;
    
      procedure A (.......);
      --
      procedure B (error_list in out l_error);  
    end PACK_DW_TEMP; 
    

    并从包体中删除type_errl_erroril_err的定义。

    【讨论】:

      猜你喜欢
      • 2014-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-17
      • 2021-12-22
      • 2016-07-25
      • 2018-08-02
      • 1970-01-01
      相关资源
      最近更新 更多