【问题标题】:Execute procedure with defined pl/sql table type in toad在 toad 中使用定义的 pl/sql 表类型执行过程
【发布时间】:2015-09-28 04:17:04
【问题描述】:

我有一个这样的包:

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

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

【问题讨论】:

  • 为什么您认为您不需要 需要将它称为 someschema.somepackage.t_str_array 来进行该分配,就像您在前几行的声明中所做的那样?
  • 如果你想初始化 in_third 局部变量,你至少需要包含包名。如果您以其他用户身份运行,则还需要包含架构名称。 IN_THIRD := someschema.somepackage.t_str_array('something'); 应该初始化 in_third 局部变量。
  • 我做了,我得到了错误:PLS-00222: no function with name 'T_STR_ARRAY' exists in this scope

标签: sql oracle plsql toad


【解决方案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

... 因为它是一个表类型,而不是一个可变数组,所以它在声明时被实例化。您不需要显式实例化它,这就是为什么 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; 

我建议您考虑更改类型的名称;给表类型起一个暗示它是数组的名称(显然!)令人困惑。它们被称为关联数组和索引表,所以你可以说它本来就很好,但我有点假设它是一个基于名称和你尝试使用它的方式的可变数组。 (当然,我应该检查一下)。

【讨论】:

  • 我尝试完全限定它并进行了拼写检查,但我仍然收到 PLS-00222 错误。
  • @user3224907 - 是的,错过了它是一个表格类型;更新了答案。您无需再次引用 t_str_array。
猜你喜欢
  • 1970-01-01
  • 2014-06-09
  • 2018-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 2019-03-26
  • 1970-01-01
相关资源
最近更新 更多