Brug af dynamisk SQL er den enkleste tilgang fra et kodningssynspunkt. Problemet med dynamisk SQL er dog, at du er nødt til hårdt at analysere hver enkelt version af forespørgslen, som ikke kun har potentialet til at beskatte din CPU, men har potentialet til at oversvømme din delte pulje med masser af ikke-delbare SQL-sætninger, og skubbe udsagn, du gerne vil cache, hvilket forårsager flere hårde parses og delte poolfragmenteringsfejl. Hvis du kører dette en gang om dagen, er det sandsynligvis ikke en større bekymring. Hvis hundredvis af mennesker udfører det tusindvis af gange om dagen, er det sandsynligvis en stor bekymring.
Et eksempel på den dynamiske SQL-tilgang
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.
Alternativt kan du bruge en samling. Dette har den fordel, at det genererer en enkelt, delbar markør, så du ikke behøver at bekymre dig om hård parsing eller oversvømmelse af den delte pulje. Men det kræver nok lidt mere kode. Den nemmeste måde at håndtere samlinger på
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.
Hvis du derimod virkelig skal starte med en kommasepareret liste over værdier, så bliver du nødt til at parse den streng til en samling, før du kan bruge den. Der er forskellige måder at parse en afgrænset streng på - min personlige favorit er at bruge regulære udtryk i en hierarkisk forespørgsel, men du kan bestemt også skrive en proceduremæssig tilgang
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.