Použití dynamického SQL je z hlediska kódování nejjednodušší přístup. Problém s dynamickým SQL je však v tom, že musíte tvrdě analyzovat každou odlišnou verzi dotazu, což má nejen potenciál zatížit váš CPU, ale má potenciál zaplavit váš sdílený fond spoustou nesdílených SQL příkazů, out příkazy, které chcete uložit do mezipaměti, což způsobuje tvrdší analýzy a chyby fragmentace sdíleného fondu. Pokud to spouštíte jednou denně, pravděpodobně to není hlavní problém. Pokud to stovky lidí provádějí tisíckrát denně, je to pravděpodobně hlavní problém.
Příklad dynamického SQL přístupu
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.
Alternativně můžete použít sbírku. To má tu výhodu, že se generuje jeden sdílený kurzor, takže se nemusíte starat o těžkou analýzu nebo zahlcení sdíleného fondu. Ale pravděpodobně to vyžaduje trochu více kódu. Nejjednodušší způsob, jak se vypořádat s kolekcemi
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.
Pokud na druhou stranu opravdu musíte začít se seznamem hodnot odděleným čárkami, pak budete muset tento řetězec analyzovat do kolekce, než jej budete moci použít. Existují různé způsoby, jak analyzovat oddělený řetězec – mým osobním favoritem je použití regulárních výrazů v hierarchickém dotazu, ale určitě byste mohli napsat i procedurální přístup
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.