Может ли табличная переменная использоваться в операторе select where? - PullRequest
4 голосов
/ 02 декабря 2011

У меня есть хранимая процедура, которая выполняет двухэтапный запрос.Первый шаг состоит в том, чтобы собрать список символов типа VARCHAR2 из таблицы и собрать их в табличную переменную, определенную так:

TYPE t_cids IS TABLE OF VARCHAR2(50) INDEX BY PLS_INTEGER;
v_cids t_cids;

Итак, в основном у меня есть:

SELECT item BULK COLLECT INTO v_cids FROM table_one;

Это работает до следующего бита.

Теперь я хочу использовать эту коллекцию в предложении where другого запроса в той же процедуре, например так:

SELECT * FROM table_two WHERE cid IN v_cids;

Есть ли способсделать это?Я могу выбрать отдельный элемент, но я бы хотел использовать переменную таблицы, как если бы я использовал обычную таблицу.Я пробовал варианты с использованием вложенных селекторов, но это тоже не сработало.

Большое спасибо,

Зак

Ответы [ 2 ]

6 голосов
/ 02 декабря 2011

У вас есть несколько вариантов достижения этой цели.

Если вы хотите использовать коллекцию, вы можете использовать функцию TABLE, чтобы выбрать из нее, но тип используемой коллекции становится важным.

для краткого примера, это создает тип базы данных, который представляет собой таблицу чисел:

CREATE TYPE number_tab AS TABLE OF NUMBER
/

Тип создан.

Затем следующий блок заполняет коллекцию и выполняет элементарный выбор из нее, используя ее в качестве таблицы и присоединяя ее к таблице EMP (с некоторым выводом, чтобы вы могли видеть, что происходит):

DECLARE
   -- Create a variable and initialise it
   v_num_tab number_tab := number_tab();
   --
   -- This is a collection for showing the output
   TYPE v_emp_tabtype IS TABLE OF emp%ROWTYPE
        INDEX BY PLS_INTEGER;
   v_emp_tab v_emp_tabtype;
BEGIN
   -- Populate the number_tab collection
   v_num_tab.extend(2);
   v_num_tab(1) := 7788;
   v_num_tab(2) := 7902;
   --
   -- Show output to prove it is populated
   FOR i IN 1 .. v_num_tab.COUNT
   LOOP
      dbms_output.put_line(v_num_tab(i));
   END LOOP;
   --
   -- Perform a select using the collection as a table
   SELECT e.*
     BULK COLLECT INTO v_emp_tab
     FROM emp e
    INNER JOIN TABLE(v_num_tab) nt
       ON (e.empno = nt.column_value);
   --
   -- Display the select output
   FOR i IN 1 .. v_emp_tab.COUNT
   LOOP
      dbms_output.put_line(v_emp_tab(i).empno||' is a '||v_emp_tab(i).job);
   END LOOP;
END;

Из этого видно, что коллекция TYPE базы данных (number_tab) считалась таблицей и могла использоваться как таковая.

Другой вариант - просто объединить две таблицы, которые вы выбираете в своем примере:

SELECT tt.*
  FROM table_two tt
 INNER JOIN table_one to
    ON (to.item = tt.cid);

Есть и другие способы сделать это, но первый может лучше всего удовлетворить ваши потребности.

Надеюсь, это поможет.

0 голосов
/ 02 декабря 2011
--Doesn't work.
--SELECT item BULK COLLECT AS 'mySelectedItems' INTO v_cids FROM table_one;

SELECT table_two.* 
FROM table_two INNER JOIN v_cids 
ON table_two.paramname = v_cids.mySelectedItems;

Если я не неправильно понял вопрос, он должен возвращать только результаты, которые находятся в табличной переменной.

Примечание: я никогда не использовал Oracle, но я думаю, что этот случай будет таким же.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...