L'uso dell'SQL dinamico è l'approccio più semplice dal punto di vista della codifica. Il problema con l'SQL dinamico, tuttavia, è che devi analizzare a fondo ogni versione distinta della query che non solo ha il potenziale di tassare la tua CPU, ma ha il potenziale per inondare il tuo pool condiviso con molte istruzioni SQL non condivisibili, spingendo out istruzioni che desideri memorizzare nella cache, causando analisi più difficili ed errori di frammentazione del pool condiviso. Se lo esegui una volta al giorno, probabilmente non è un grosso problema. Se centinaia di persone lo eseguono migliaia di volte al giorno, è probabilmente una delle principali preoccupazioni.
Un esempio dell'approccio SQL dinamico
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.
In alternativa, puoi utilizzare una raccolta. Questo ha il vantaggio di generare un singolo cursore condivisibile in modo da non doversi preoccupare di un'analisi difficile o di inondare il pool condiviso. Ma probabilmente richiede un po' più di codice. Il modo più semplice per gestire le collezioni
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.
Se, d'altra parte, devi davvero iniziare con un elenco di valori separati da virgole, dovrai analizzare quella stringa in una raccolta prima di poterla utilizzare. Esistono vari modi per analizzare una stringa delimitata:il mio preferito è usare espressioni regolari in una query gerarchica, ma potresti anche scrivere un approccio procedurale
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.