Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Por que não podemos usar cursor ref forte com instrução SQL dinâmica?


Aqui está um procedimento com um cursor ref fortemente 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>

Esta próxima instrução falha porque a assinatura do registro EMP não corresponde à da tabela 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>

Mas se alterarmos a projeção para corresponder à tabela DEPT, teremos sucesso novamente:
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>

Então, por que não podemos usar um ref-cursor fortemente tipado com 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 o compilador não pode analisar a string na instrução SQL dinâmica. Portanto, ele não pode afirmar que as colunas na projeção da consulta correspondem em número e tipo de dados à assinatura do cursor ref. Conseqüentemente, ele não pode validar o contrato entre a variável do cursor ref e a consulta. Fica ainda mais fácil entender por que isso não pode ser permitido quando consideramos que a instrução SQL dinâmica pode ser montada a partir de uma consulta em USER_TAB_COLUMNS.