L'utilisation de SQL dynamique est l'approche la plus simple du point de vue du codage. Le problème avec SQL dynamique, cependant, est que vous devez analyser chaque version distincte de la requête, ce qui non seulement a le potentiel de taxer votre CPU, mais a le potentiel d'inonder votre pool partagé avec de nombreuses instructions SQL non partageables, poussant out que vous souhaitez mettre en cache, ce qui provoque davantage d'analyses difficiles et d'erreurs de fragmentation du pool partagé. Si vous l'exécutez une fois par jour, ce n'est probablement pas un problème majeur. Si des centaines de personnes l'exécutent des milliers de fois par jour, c'est probablement une préoccupation majeure.
Un exemple de l'approche SQL dynamique
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.
Vous pouvez également utiliser une collection. Cela a l'avantage de générer un seul curseur partageable, vous n'avez donc pas à vous soucier de l'analyse difficile ou de l'inondation du pool partagé. Mais cela nécessite probablement un peu plus de code. La façon la plus simple de gérer les collections
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.
Si, d'un autre côté, vous devez vraiment commencer avec une liste de valeurs séparées par des virgules, vous devrez alors analyser cette chaîne dans une collection avant de pouvoir l'utiliser. Il existe différentes façons d'analyser une chaîne délimitée - ma préférée est d'utiliser des expressions régulières dans une requête hiérarchique, mais vous pouvez certainement également écrire une approche procédurale
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.