sql >> Base de Datos >  >> RDS >> Oracle

¿Por qué no podemos usar un cursor de referencia fuerte con una instrucción SQL dinámica?

Aquí hay un procedimiento con un cursor de referencia fuertemente tipado:

SQL> create or replace procedure p1 is
  2      type dept_rc is ref cursor return dept%rowtype;
  3      my_ref_cursor dept_rc;
  4  begin
  5      open my_ref_cursor for
  6          select * from dept;
  7  end;
  8  /

Procedure created.

SQL>

La siguiente instrucción falla porque la firma del registro EMP no coincide con la de la tabla DEPT.

SQL> create or replace procedure p1 is
  2      type dept_rc is ref cursor return dept%rowtype;
  3      my_ref_cursor dept_rc;
  4  begin
  5      open my_ref_cursor for
  6          select * from emp;
  7  end;
  8  /

Warning: Procedure created with compilation errors.

SQL> show error
Errors for PROCEDURE P1:

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/5      PL/SQL: SQL Statement ignored
6/9      PLS-00382: expression is of wrong type

SQL>

Pero si cambiamos la proyección para que coincida con la tabla DEPT, tendremos éxito nuevamente:

SQL> create or replace procedure p1 is
  2      type dept_rc is ref cursor return dept%rowtype;
  3      my_ref_cursor dept_rc;
  4  begin
  5      open my_ref_cursor for
  6          select deptno, ename, job from emp;
  7  end;
  8  /

Procedure created.

SQL>

Entonces, ¿por qué no podemos usar un cursor de referencia fuertemente tipado con SQL dinámico?

SQL> create or replace procedure p1 is
  2      type dept_rc is ref cursor return dept%rowtype;
  3      my_ref_cursor dept_rc;
  4  begin
  5      open my_ref_cursor for
  6          'select * from dept';
  7  end;
  8  /

Warning: Procedure created with compilation errors.

SQL> show error
Errors for PROCEDURE P1:

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/5      PL/SQL: Statement ignored
5/10     PLS-00455: cursor 'MY_REF_CURSOR' cannot be used in dynamic SQL
         OPEN statement

SQL>

Porque el compilador no puede analizar la cadena en la instrucción SQL dinámica. Por lo tanto, no puede afirmar que las columnas en la proyección de la consulta coincidan en número y tipo de datos con la firma del cursor de referencia. En consecuencia, no puede validar el contrato entre la variable de cursor ref y la consulta. Es aún más fácil entender por qué esto no se puede permitir si consideramos que la instrucción SQL dinámica podría ensamblarse a partir de una consulta en USER_TAB_COLUMNS.