Използването на динамичен SQL е най-простият подход от гледна точка на кодирането. Проблемът с динамичния SQL обаче е, че трябва да анализирате трудно всяка отделна версия на заявката, която не само има потенциала да натовари вашия процесор, но има потенциала да наводни вашия споделен пул с много SQL изрази, които не могат да се споделят, натискайки out изрази, които искате да кеширате, което води до по-трудни анализи и грешки при фрагментиране на споделен пул. Ако изпълнявате това веднъж на ден, това вероятно не е сериозно притеснение. Ако стотици хора го изпълняват хиляди пъти на ден, това вероятно е голямо притеснение.
Пример за динамичен SQL подход
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_deptnos varchar2(100) := '10,20';
3 l_rc sys_refcursor;
4 l_dept_rec dept%rowtype;
5 begin
6 open l_rc for 'select * from dept where deptno in (' || l_deptnos || ')';
7 loop
8 fetch l_rc into l_dept_rec;
9 exit when l_rc%notfound;
10 dbms_output.put_line( l_dept_rec.dname );
11 end loop;
12 close l_rc;
13* end;
SQL> /
ACCOUNTING
RESEARCH
PL/SQL procedure successfully completed.
Като алтернатива можете да използвате колекция. Това има предимството да генерира един единствен курсор, който може да се споделя, така че не е нужно да се притеснявате за тежък анализ или наводняване на споделения пул. Но вероятно изисква малко повече код. Най-простият начин за работа с колекции
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_deptnos tbl_deptnos := tbl_deptnos(10,20);
3 begin
4 for i in (select *
5 from dept
6 where deptno in (select column_value
7 from table(l_deptnos)))
8 loop
9 dbms_output.put_line( i.dname );
10 end loop;
11* end;
SQL> /
ACCOUNTING
RESEARCH
PL/SQL procedure successfully completed.
Ако, от друга страна, наистина трябва да започнете със списък със стойности, разделени със запетая, тогава ще трябва да анализирате този низ в колекция, преди да можете да го използвате. Има различни начини за анализиране на разделен низ – моят личен фаворит е да използвам регулярни изрази в йерархична заявка, но със сигурност бихте могли да напишете и процедурен подход
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_deptnos tbl_deptnos;
3 l_deptno_str varchar2(100) := '10,20';
4 begin
5 select regexp_substr(l_deptno_str, '[^,]+', 1, LEVEL)
6 bulk collect into l_deptnos
7 from dual
8 connect by level <= length(replace (l_deptno_str, ',', NULL));
9 for i in (select *
10 from dept
11 where deptno in (select column_value
12 from table(l_deptnos)))
13 loop
14 dbms_output.put_line( i.dname );
15 end loop;
16* end;
17 /
ACCOUNTING
RESEARCH
PL/SQL procedure successfully completed.