Как я могу использовать коллекцию в инструкции Oracle SQL

Я хочу написать функцию 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;

к сожалению, часть "не в MyList" не является допустимым SQL. Есть ли способ достичь этого?

4 ответов


то, что вы ищете-это 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;

вы можете сделать это так:

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).


Если вы используете 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;

дополнительные сведения см. В разделе этот пост


-- INT_LIST объявляется глобально как " тип INT_LIST-это таблица Целое число"

Это похоже на объявление PL / SQL. Инструкции SELECT используют SQL engine. Это означает, что вам нужно объявить свой тип в SQL.

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.