Oracle
 sql >> Base de données >  >> RDS >> Oracle

Pourquoi ne pouvons-nous pas utiliser un curseur de référence fort avec une instruction SQL dynamique ?

Voici une procédure avec un curseur de référence fortement typé :

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>

Cette instruction suivante échoue car la signature de l'enregistrement EMP ne correspond pas à celle de la table 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>

Mais si nous modifions la projection pour qu'elle corresponde à la table DEPT, nous réussissons à nouveau :

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>

Alors, pourquoi ne pouvons-nous pas utiliser un curseur de référence fortement typé avec SQL dynamique ?

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>

Parce que le compilateur ne peut pas analyser la chaîne dans l'instruction SQL dynamique. Il ne peut donc pas affirmer que les colonnes de la projection de la requête correspondent en nombre et en type de données à la signature du curseur de référence. Par conséquent, il ne peut pas valider le contrat entre la variable de curseur ref et la requête. Il est encore plus facile de comprendre pourquoi cela ne peut pas être autorisé lorsque l'on considère que l'instruction SQL dynamique pourrait être assemblée à partir d'une requête sur USER_TAB_COLUMNS.