Использование переменной связывания в предложении IN
Я хочу запросить список чисел в переменную plsql и использовать его в предложении in в другом запросе sql. Я создал тестовый пример ниже того, что я хочу сделать.
Я сделал Google для решения, и я думаю, что это должно быть как-то возможно, но я просто не могу запустить его. Пожалуйста, помогите мне с компиляцией решения.
CREATE OR REPLACE PROCEDURE PROCEDURE1
as
type t_id is table of number;
v_ids t_id;
v_user_ids number;
BEGIN
-- fill variable v_id with id's, user_id is of type number
select user_id
bulk collect into v_ids
from user_users;
-- then at a later stage ... issue a query using v_id in the in clause
select user_id into v_user_ids from user_users
-- this line does not compile ( local collection type not allowed in SQL statements)
where user_id in ( v_ids );
END PROCEDURE1;
1 ответ
Используя тип SQL:
SQL> create type t_id is table of number;
2 /
Type created.
SQL> CREATE OR REPLACE PROCEDURE PROCEDURE1
2 as
3 v_ids t_id;
4 v_user_ids number;
5 BEGIN
6
7 -- fill variable v_id with id's, user_id is of type number
8 select user_id
9 bulk collect into v_ids
10 from user_users
11 where user_id between 100 and 120;
12
13 select user_id into v_user_ids
14 from user_users
15 where user_id in (select /*+ cardinality(t, 10) */ t.column_value from table(v_ids) t)
16 and rownum = 1;
17
18 dbms_output.put_line(v_user_ids);
19
20 END PROCEDURE1;
21 /
Procedure created.
SQL> exec procedure1
100
где cardinality(t, 10)
должно быть разумное предположение о том, сколько элементов в вашем массиве.
примечание: использование неограниченного массового сбора, как у вас:
8 select user_id
9 bulk collect into v_ids
10 from user_users;
как правило, не очень хорошо, если ваш массив может содержать много тысяч или более строк, так как вы слишком сильно нагружаете память и в конечном итоге выведите код из строя. Вам бы лучше обслужить с явным курсором open x for ..
и массовая выборка в цикле с предложением limit, т.е. fetch x bulk collect into v_ids limit 100
и обрабатывать партиями скажем 100-1000.