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.