Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Warum können wir keinen Strong-Ref-Cursor mit dynamischer SQL-Anweisung verwenden?

Hier ist eine Prozedur mit einem stark typisierten Ref-Cursor:

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>

Diese nächste Anweisung schlägt fehl, da die Signatur des EMP-Datensatzes nicht mit der der DEPT-Tabelle übereinstimmt.

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>

Aber wenn wir die Projektion an die DEPT-Tabelle anpassen, dann haben wir wieder Erfolg:

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>

Warum können wir also keinen stark typisierten Ref-Cursor mit dynamischem SQL verwenden?

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>

Weil der Compiler die Zeichenfolge in der dynamischen SQL-Anweisung nicht analysieren kann. Es kann also nicht behaupten, dass die Spalten in der Projektion der Abfrage in Anzahl und Datentyp mit der Signatur des Ref-Cursors übereinstimmen. Folglich kann es den Vertrag zwischen der Ref-Cursor-Variablen und der Abfrage nicht validieren. Es ist noch einfacher zu verstehen, warum dies nicht erlaubt werden kann, wenn wir bedenken, dass die dynamische SQL-Anweisung aus einer Abfrage auf USER_TAB_COLUMNS zusammengestellt werden könnte.