厳密に型指定された ref カーソルを使用するプロシージャを次に示します。
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>
EMP レコードの署名が 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>
しかし、射影を 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 deptno, ename, job from emp;
7 end;
8 /
Procedure created.
SQL>
では、動的 SQL で厳密に型指定された 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 /
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>
コンパイラは動的 SQL ステートメント内の文字列を解析できないためです。そのため、クエリのプロジェクション内の列の数とデータ型が ref カーソルのシグネチャと一致するとは断言できません。したがって、ref カーソル変数とクエリの間のコントラクトを検証できません。USER_TAB_COLUMNS に対するクエリから動的 SQL ステートメントを組み立てることができると考えると、なぜこれが許可されないのかを理解するのはさらに簡単です。