コーディングの観点からは、動的 SQL を使用するのが最も簡単な方法です。ただし、動的 SQL の問題は、クエリのすべての異なるバージョンをハード解析する必要があることです。これは、CPU に負担をかける可能性があるだけでなく、共有プールを共有不可能な多数の SQL ステートメントで溢れさせる可能性があり、プッシュします。キャッシュしたいステートメントがなくなると、よりハードな解析と共有プールの断片化エラーが発生します。これを 1 日 1 回実行している場合、それはおそらく大きな問題ではありません。何百人もの人々が 1 日に何千回も実行している場合、それはおそらく大きな問題です。
動的 SQL アプローチの例
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.
または、コレクションを使用することもできます。これには、単一の共有可能なカーソルが生成されるという利点があるため、ハード解析や共有プールのフラッディングについて心配する必要はありません。ただし、おそらくもう少しコードが必要です。コレクションを扱う最も簡単な方法
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.
一方、コンマ区切りの値のリストから実際に開始する必要がある場合は、その文字列を使用する前にコレクションに解析する必要があります。区切られた文字列を解析するにはさまざまな方法があります。私の個人的なお気に入りは、階層クエリで正規表現を使用することですが、手続き型のアプローチを書くこともできます。
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.