【问题标题】:How can I use a collection within an Oracle SQL statement如何在 Oracle SQL 语句中使用集合
【发布时间】:2011-11-26 01:29:50
【问题描述】:

我想编写一个 Oracle 函数,它将多个步骤中的一些数据收集到一个集合变量中,并在一个 SELECT 查询中使用该集合数据,就像这个非常简化的示例一样:

CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
  -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER"
  MyList INT_LIST := INT_LIST();
  MyName VARCHAR2(512);
BEGIN
  MyList.Extend(3);
  MyList(0) := 1;
  MyList(1) := 2;
  MyList(2) := 3;

  SELECT Name INTO MyName
  FROM Item WHERE ItemId NOT IN MyList;
  RETURN MyName;
END TESTFUNC01;

不幸的是,“NOT IN MyList”部分不是有效的 SQL。有没有办法做到这一点?

【问题讨论】:

    标签: oracle collections plsql


    【解决方案1】:

    您正在寻找的是table 函数:

    CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
      -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER"
      MyList INT_LIST := INT_LIST();
      MyName VARCHAR2(512);
    BEGIN
      MyList.Extend(3);
      MyList(1) := 1;
      MyList(2) := 2;
      MyList(3) := 3;
    
      SELECT Name INTO MyName
      FROM Item WHERE ItemId NOT IN (select * from table(MyList));
      RETURN MyName;
    END TESTFUNC01;
    

    【讨论】:

    • 这就是我想要的。非常感谢。
    【解决方案2】:

    你可以这样做:

    CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
      -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER"
      MyList INT_LIST := INT_LIST();
      MyName VARCHAR2(512);
    BEGIN
      MyList.Extend(3);
      MyList(1) := 1;
      MyList(2) := 2;
      MyList(3) := 3;
    
      SELECT Name INTO MyName
      FROM Item WHERE ItemId NOT IN (SELECT COLUMN_VALUE FROM TABLE(MyList));
      RETURN MyName;
    END TESTFUNC01;
    

    请注意,我还更改了列表索引。以 1 开头(不是 0)。

    【讨论】:

      【解决方案3】:

      如果您使用 oracle 10,您可以使用集合扩展:

      CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
        -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER"
        MyList INT_LIST := INT_LIST();
        MyName VARCHAR2(512);
      BEGIN
        MyList.Extend(3);
        MyList(1) := 1;
        MyList(2) := 2;
        MyList(3) := 3;
      
        SELECT Name INTO MyName
        FROM Item WHERE ItemId MEMBER OF MyList;
        RETURN MyName;
      END TESTFUNC01;
      

      更多详情请见this post

      【讨论】:

        【解决方案4】:

        -- INT_LIST 全局声明为“TYPE INT_LIST IS TABLE OF 整数”

        这看起来像一个 PL/SQL 声明。 SELECT 语句使用 SQL 引擎。这意味着您需要在 SQL 中声明您的 TYPE。

        CREATE TYPE INT_LIST AS TABLE OF NUMBER(38,0);
        /
        

        然后你可以在 SELECT 语句中使用它:

        SELECT Name INTO MyName
        FROM Item WHERE ItemId NOT IN (select * from table(MyList));
        

        当然,您需要确保您的查询只返回一行,或者您的程序处理 TOO_MANY_ROWS 异常。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-11
          • 1970-01-01
          • 2019-09-02
          • 1970-01-01
          • 2021-11-12
          • 1970-01-01
          相关资源
          最近更新 更多