使用已定义的 pl/sql table 类型在蟾蜍中执行程序

Execute procedure with defined pl/sql table type in toad

我有这样的包裹:

CREATE OR REPLACE PACKAGE someschema.somepackage
AS
    TYPE t_str_array IS TABLE OF VARCHAR2 (500)
                       INDEX BY BINARY_INTEGER;
    PROCEDURE some_procedure_p (in_first IN NUMBER, 
    in_second IN VARCHAR2, 
    in_third IN t_str_array, 
    in_fourth IN date, 
    in_fifth IN date,
    out_sixth_cur OUT t_some_ref);
END;
/

CREATE OR REPLACE PACKAGE BODY someschema.somepackage
AS   
   PROCEDURE some_procedure_p (in_first IN NUMBER, 
        in_second IN VARCHAR2, 
        in_third IN t_str_array, 
        in_fourth IN date, 
        in_fifth IN date,
        out_sixth_cur OUT t_some_ref);
        IS
        BEGIN
              FOR i IN in_third.FIRST .. in_third.LAST
              LOOP
                 ... do something
              END LOOP COMMIT;

              OPEN out_sixth_cur FOR
                 SELECT ... something;
        END;
END somepackage;

如何在 toad 中执行此过程?到目前为止我已经尝试过:

右键程序,点击执行包,自动生成调用代码:

DECLARE 
  IN_FIRST NUMBER;
  IN_SECOND VARCHAR2(32767);
  IN_THIRD someschema.somepackage.t_str_array;
  IN_FOURTH DATE;
  IN_FIFTH DATE;
  OUT_SIXTH_CUR someschema.somepackage.t_some_ref;

BEGIN 
  IN_FIRST := NULL;
  IN_SECOND:= NULL;
  IN_FOURTH := NULL;
  IN_FIFTH := NULL;
  OUT_SIXTH_CUR := NULL;

  someschema.somepackage.some_procedure_p ( IN_FIRST, IN_SECOND, IN_THIRD, IN_FOURTH, IN_FIFTH, OUT_SIXTH_CUR );

  :rc0_OUT_SIXTH_CUR := OUT_SIXTH_CUR;

  COMMIT; 
END; 

我补充了:

  IN_THIRD := t_str_array('something');

但是当我运行这样的时候,我得到了以下错误:

PLS-00201: identifier 'T_STR_ARRAY' must be declared

如果我已经在包规范中定义了这种类型,为什么会出现这个错误??我也尝试过很多其他方法,但总是抱怨类型。

您在进行分配时需要完全限定类型名称(至少在包级别;如果它是您的包,则模式是多余的但在这里不会受到伤害),以及在声明它时你的匿名块:

IN_THIRD := someschema.somepackage.t_str_array('something');

database/schema 级别没有任何东西称为 t_str_array,如果您不限定它,Oracle 不知道它需要来自包。您可能认为这很明显;但是没有什么能阻止你在多个包中定义相同的类型名称,所以你必须清晰一致。

但是正如你所指出的,你会得到

PLS-00222: no function with name 'T_STR_ARRAY' exists in this scope

... 因为它是 table 类型,而不是 varray,所以它在声明时被实例化。您不需要显式实例化它,这就是 Toad 没有为您完成的原因。 The documentation 表明这种类型的集合被初始化为 'empty' 而不是 null。

要填充它,您只需使用索引位置分配一个值:

IN_THIRD(1) := 'something';

所以整个块将变成:

DECLARE 
  IN_FIRST NUMBER;
  IN_SECOND VARCHAR2(32767);
  IN_THIRD someschema.somepackage.t_str_array;
  IN_FOURTH DATE;
  IN_FIFTH DATE;
  OUT_SIXTH_CUR someschema.somepackage.t_some_ref;

BEGIN 
  IN_FIRST := NULL;
  IN_SECOND:= NULL;
  IN_THIRD(1) := 'something';
  IN_FOURTH := NULL;
  IN_FIFTH := NULL;
  OUT_SIXTH_CUR := NULL;

  someschema.somepackage.some_procedure_p ( IN_FIRST, IN_SECOND, IN_THIRD, IN_FOURTH, IN_FIFTH, OUT_SIXTH_CUR );

  :rc0_OUT_SIXTH_CUR := OUT_SIXTH_CUR;

  COMMIT; 
END; 

不过,我建议您考虑更改类型的名称;给 table 类型一个表明它是数组的名称(显然!)令人困惑。它们被称为关联数组和索引 tables,所以你可以说它很好,但我有点假设它是一个基于名称和你如何使用它的 varray . (我当然应该检查一下)。