El uso de SQL dinámico es el enfoque más simple desde el punto de vista de la codificación. Sin embargo, el problema con el SQL dinámico es que tiene que analizar cada versión distinta de la consulta, lo que no solo tiene el potencial de gravar su CPU, sino que también tiene el potencial de inundar su grupo compartido con muchas declaraciones SQL no compartibles, empujando out declaraciones que le gustaría almacenar en caché, lo que provoca más análisis duros y errores de fragmentación del grupo compartido. Si está ejecutando esto una vez al día, probablemente no sea una preocupación importante. Si cientos de personas lo ejecutan miles de veces al día, es probable que sea una gran preocupación.
Un ejemplo del enfoque de SQL dinámico
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.
Alternativamente, puede usar una colección. Esto tiene la ventaja de generar un solo cursor compartible para que no tenga que preocuparse por el análisis duro o la inundación del grupo compartido. Pero probablemente requiera un poco más de código. La forma más sencilla de gestionar los cobros
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, por otro lado, realmente tiene que comenzar con una lista de valores separados por comas, entonces tendrá que analizar esa cadena en una colección antes de poder usarla. Hay varias formas de analizar una cadena delimitada:mi favorito personal es usar expresiones regulares en una consulta jerárquica, pero ciertamente también podría escribir un enfoque de procedimiento
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.