Oracle
 sql >> Database >  >> RDS >> Oracle

Perché non possiamo usare un forte cursore di riferimento con l'istruzione SQL dinamica?

Ecco una procedura con un cursore di riferimento fortemente tipizzato:

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>

Questa istruzione successiva non riesce perché la firma del record EMP non corrisponde a quella della tabella 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>

Ma se cambiamo la proiezione in modo che corrisponda alla tabella DEPT, abbiamo di nuovo successo:

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>

Quindi, perché non possiamo usare un cursore di riferimento fortemente tipizzato con SQL dinamico?

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>

Perché il compilatore non può analizzare la stringa nell'istruzione SQL dinamica. Quindi non può affermare che le colonne nella proiezione della query corrispondano in numero e tipo di dati alla firma del cursore di riferimento. Di conseguenza non può convalidare il contratto tra la variabile del cursore di riferimento e la query. È ancora più facile capire perché ciò non può essere consentito se consideriamo che l'istruzione SQL dinamica potrebbe essere assemblata da una query su USER_TAB_COLUMNS.