这是一个带有强类型引用游标的过程:
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的强类型引用游标?
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语句时,更容易理解为什么不允许这样做.