【问题标题】:Using type "is table of" in a select statement在 select 语句中使用类型“is table of”
【发布时间】:2015-05-28 11:02:04
【问题描述】:

我正在尝试创建一个 select 语句来选择在之前的 select 语句中选择的字段,按照以下代码(使用 oracle 11g):

    Declare 
    type NumberArray IS TABLE OF Number;
    v_medium NumberArray;
    v_medium_final NumberArray := NumberArray(); 
    v_count number;
    type VarcharArray IS TABLE OF VARCHAR2(60);
    v_Type VarcharArray
    --Select all Regions and Locality affected by the fault
    cursor Locality_cur is
      Select LocalityCode from AvaFaultLocality where FAULTID=36841 and SITEID=1;
      Locality_rec Locality_cur%ROWTYPE;
    cursor Region_cur is
      Select RegionCode  from avafaultregion where FAULTID=36841 and SITEID=1;
      Region_rec Region_cur%ROWTYPE;
Begin
      v_count := 1; 
      FOR Region_rec IN Region_cur
      LOOP
        dbms_output.put_line(Region_rec.RegionCode);
        Select RECIPIENTMEDIUMID BULK COLLECT into v_medium from  AvaRecipientAreaRegion where RegionCode = Region_rec.RegionCode;

       FOR idx IN 1..v_medium.COUNT LOOP
         v_medium_final.extend(); 
         v_medium_final(v_count) := v_medium(idx); 
         dbms_output.put_line(TO_CHAR(v_medium(idx)));
         v_count:= v_count + 1;
       END LOOP;  
       dbms_output.put_line('End Loop for Region '||Region_rec.RegionCode);     
      END LOOP;
      dbms_output.put_line(TO_CHAR(v_medium_final.count));
      Select MEDIUMTYPECODE BULK COLLECT into v_Type from AvaRecipientMedium where RECIPIENTMEDIUMID in (SELECT * FROM TABLE(v_medium_final)); <--- Line with problem
End;

主要我要做的是选择所有区域的内容,循环这个结果并获取这些区域中所有位置的内容,然后获取每个位置的所有 RecipientMediumID 并将结果添加到一个名为的变量中v_medium_final。这部分工作完美。 问题是当我尝试使用此选择的结果来选择 RecipientMedium 表中的值时,其中所有值都在变量 v_medium_final 中。

我尝试使用:

Select MEDIUMTYPECODE BULK COLLECT into v_Type from AvaRecipientMedium where RECIPIENTMEDIUMID in (SELECT * FROM TABLE(v_medium_final));

Select MEDIUMTYPECODE BULK COLLECT into v_Type from AvaRecipientMedium where RECIPIENTMEDIUMID in v_medium_final;

但我总是得到错误:

 [Error] Execution (32: 126): ORA-06550: line 32, column 126:
PLS-00642: local collection types not allowed in SQL statements
ORA-06550: line 32, column 120:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
ORA-06550: line 32, column 7:
PL/SQL: SQL Statement ignored

对于第二种情况: [错误] 执行(32:106):ORA-06550:第 32 行,第 106 列:

PLS-00642: local collection types not allowed in SQL statements

【问题讨论】:

    标签: sql oracle select oracle11g oracle-sqldeveloper


    【解决方案1】:

    如错误所示,您不能使用本地集合类型。您需要使用在 SQL 级别定义的集合类型。

    CREATE TYPE NumberArray
        AS TABLE OF NUMBER;
    
    DECLARE
      v_medium NumberArray;
      ...
    

    这将要求您拥有CREATE TYPE 权限,这意味着您的类型定义将对任何有权查看它的人可见,而不仅仅是您的 PL/SQL 块的范围。

    就我个人而言,我会避免在不是VARRAY 的集合类型的名称中使用Array,因为名称可能会造成混淆。如果我看到NumberArray 类型,我猜想它被定义为VARRAY(n) OF NUMBER 而不是嵌套表类型。对嵌套表类型使用ntt 后缀似乎更明智 (create type number_ntt as table of number)。

    【讨论】:

    • 谢谢贾斯汀我一直在寻找解决方案几个小时,以及命名约定的提示。
    • 这个解决方案在我将它作为 SQL 调用时运行良好,现在我正在尝试将其转换为包但我无法在其上使用 create 命令,你能再帮我一次吗?谢谢
    • @IcaroNZ - 我不确定我是否理解这个问题。如果要在 SQL 语句中使用集合,则必须在 PL/SQL 中定义集合类型。所以类型定义必须在包之外。您可以在包中声明使用您已声明的 SQL 类型的变量,但不能在 PL/SQL 中声明该类型,然后在 SQL 中使用它(至少在您的 Oracle 版本中,该限制在 12.1 中放宽了) .
    • 基本上我要做的是创建一个包,该包创建一个数字列表并检查使用 where 子句中的这些数字作为 ListOfNumbers 中的数字的选择语句。我已经在这方面工作了两天,你能指出我正确的方向吗?谢谢
    • @IcaroNZ - 我仍然没有看到包如何改变任何东西。您运行 CREATE TYPE 语句来创建类型。您运行CREATE PACKAGE 语句来创建包。您(假设包包含过程或函数)运行CREATE PACKAGE BODY 语句来创建包主体。这些需要是创建三个独立数据库对象的三个独立语句。
    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 2010-10-11
    • 2011-07-07
    • 1970-01-01
    相关资源
    最近更新 更多