【问题标题】:PLSQL script not working with passing multiple values into IN() calusePL SQL 脚本无法将多个值传递给 IN() 子句
【发布时间】:2017-12-11 13:15:43
【问题描述】:

我是 PLSQL 的新手,我想将一个数字数组传递给 IN() 子句值,但是 Sqldeveloper 抛出以下错误消息:

Error report -
ORA-06550: line 11, column 60:
PLS-00382: expression is of wrong type
ORA-06550: line 11, column 53:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
ORA-06550: line 10, column 4:
PL/SQL: SQL Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

这是我的代码:

DECLARE
   TYPE sc IS TABLE OF transactionhistory.NBSUBCOMPANY%TYPE INDEX BY PLS_INTEGER; 
   arr sc;
BEGIN
   arr(0) := 000;
   arr(1) := 111;
   arr(2) := 222;
   arr(3) := 333;

   select count(th.CHCARDNUMBER) as transactions from transactionhistory th INNER JOIN cards ch on ch.NBATTMID=th.NBATTMID where th.dtdate>=to_date('01-oct-2016','dd-mon-yyyy') and th.dtdate<to_date('01-nov-2016','dd-mon-yyyy') 
   and ch.NBSUBCOMPANY IN (select column_value from table (arr))
   and ((th.CHTRANSTYPE in ('2940', '2916', '2941', '2942', '2943', '2944', '2945', '2902', '2917', '2925') and th.NBBASEAMT < 0) or (th.CHTRANSTYPE in ('2922', '2923', '2926', '2950', '2951', '2952', '2953', '2954', '2955') and th.NBBASEAMT > 0) or (th.CHTRANSTYPE in ('1101', '1102', '1104', '1105', '1106', '1107', '1109') and th.BASEII_STATUS = 'C') or th.CHTRANSTYPE not in ('2940', '2916', '2941', '2942', '2943', '2944', '2945', '2902', '2917', '2925', '2922', '2923', '2926', '2950', '2951', '2952', '2953', '2954', '2955', '1101', '1102', '1104', '1105', '1106', '1107', '1109')); 
END;

请建议我如何通过这个。

【问题讨论】:

  • @XING 感谢您的回复,但情况有所不同,我已经访问了 URL,他们没有将值传递到 IN() 他们只是像数组上的简单迭代器一样逐个打印值。但我想将整个数组传递给 IN()。

标签: plsql oracle11g


【解决方案1】:

您可以使用MEMBER OF 子句。见下文:

正如@Sudipta 提到的,您不能像现在一样使用在 PLSQL 块中贴花的集合,您需要在 PLSQL block 之外声明它。

CREATE OR REPLACE TYPE sc IS TABLE OF NUMBER;

然后

DECLARE
  -- TYPE sc IS TABLE OF NUMBER INDEX BY PLS_INTEGER;

   arr   sc:=sc();

   num number;

BEGIN
   arr.extend(4);
   arr(1) := 0;
   arr(2) := 1;
   arr(3) := 2;
   arr(4) := 3;

   Select count(1)
   into num
   from employee 
   -- You can use either commented one or uncommented one. your choice. 
   --where employee_id in (select column_value from table(arr));
   where employee_id member of arr;

END;

【讨论】:

    【解决方案2】:

    您需要有一个解决方法。

    SQL 不支持以您想要的方式使用本地集合类型。

    下面的示例程序将有助于解决问题

    CREATE OR REPLACE type TEST_TYPE
    IS
        TABLE OF NUMBER;
    

    您需要在数据库中创建一个类型才能使其工作。可以在一个包中创建,如果你有的话。

    DECLARE
        TEST_VAR TEST_TYPE := TEST_TYPE();
    BEGIN
        TEST_VAR.extend(1);
        TEST_VAR(TEST_VAR.last) := 222;
        TEST_VAR.extend(1);
        TEST_VAR(TEST_VAR.last) := 333;
    
        FOR rec IN
        (SELECT column_value
        FROM TABLE(TEST_VAR)
        )
        LOOP
            dbms_output.put_line(rec.column_value);
    
        END LOOP;
    
    END;
    

    输出

    222
    333
    

    这样,您可以将select column_value from table(test_var) 用于您的IN() 子句。

    此外,您不一定需要遵循extend(i) 部分。您也可以简单地执行以下操作

    TEST_VAR TEST_TYPE := TEST_TYPE(222,333);
    

    阅读 - local collection types not allowed in SQL statements

    【讨论】:

      猜你喜欢
      • 2022-06-10
      • 2015-04-28
      • 2020-04-23
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      • 2021-03-01
      相关资源
      最近更新 更多