Att använda dynamisk SQL är den enklaste metoden ur kodningssynpunkt. Problemet med dynamisk SQL är dock att du måste analysera varje distinkt version av frågan som inte bara har potentialen att belasta din CPU utan har potentialen att översvämma din delade pool med massor av icke-delbara SQL-satser, tryckande ut uttalanden som du vill cachelagra, vilket orsakar fler hårda analyser och delade poolfragmenteringsfel. Om du kör detta en gång om dagen är det förmodligen inte ett större problem. Om hundratals människor utför det tusentals gånger om dagen är det förmodligen ett stort problem.
Ett exempel på den dynamiska SQL-metoden
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 använda en samling. Detta har fördelen av att generera en enda, delbar markör så att du inte behöver oroa dig för hård analys eller översvämning av den delade poolen. Men det kräver nog lite mer kod. Det enklaste sättet att hantera samlingar
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.
Om du å andra sidan verkligen måste börja med en kommaseparerad lista med värden, måste du tolka den strängen till en samling innan du kan använda den. Det finns olika sätt att tolka en avgränsad sträng - min personliga favorit är att använda reguljära uttryck i en hierarkisk fråga, men du kan säkert också skriva ett procedurmässigt tillvägagångssätt
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.