在toad

时间:2015-07-09 16:36:24

标签: sql oracle plsql 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

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

1 个答案:

答案 0 :(得分:1)

您需要在执行任务时完全限定类型名称(至少要打包级别;如果您的程序包仍然是程序包,那么架构是多余的,但这里不会受到伤害),以及何时你在匿名区块中声明它:

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

数据库/架构级别没有任何内容称为t_str_array,如果您没有资格,Oracle并不知道它需要来自程序包。你可能认为这很明显;但是没有什么可以阻止你在多个包装中定义相同的类型名称,所以你必须清楚和一致。

但正如你指出的那样,你得到了

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

...因为它是一个表类型,而不是一个varray,所以它在声明时被实例化。你不需要明确地实例化它,这就是为什么Toad没有为你做到这一点。 The documentation显示此类型的集合已初始化为“空”'而不是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; 

我建议您考虑更改类型的名称;给表格类型一个名称,表明它的数组(显然!)令人困惑。它们被称为关联数组和索引表,因此您可以认为它很好,但我认为它是基于名称和您尝试使用它的方式的varray。 (当然,我应该检查一下。)