Oracle 为什么不能在动态SQL语句中使用强引用游标?
我试图使用带有动态sql语句的强引用cur,但它给出了一个错误,但是当我使用弱游标时,它可以工作,请解释原因并 转发给我oracle server architect的任何链接,其中包含有关如何在oracle server中进行编译和解析的内容。这是错误和代码Oracle 为什么不能在动态SQL语句中使用强引用游标?,oracle,plsql,dynamic-sql,Oracle,Plsql,Dynamic Sql,我试图使用带有动态sql语句的强引用cur,但它给出了一个错误,但是当我使用弱游标时,它可以工作,请解释原因并 转发给我oracle server architect的任何链接,其中包含有关如何在oracle server中进行编译和解析的内容。这是错误和代码 ERROR at line 6: ORA-06550: line 6, column 7: PLS-00455: cursor 'EMP_REF_CUR' cannot be used in dynamic SQL OPEN statem
ERROR at line 6:
ORA-06550: line 6, column 7:
PLS-00455: cursor 'EMP_REF_CUR' cannot be used in dynamic SQL OPEN statement
ORA-06550: line 6, column 2:
PL/SQL: Statement ignored
declare
type ref_cur_type IS REF CURSOR RETURN employees%ROWTYPE; --Creating a strong REF cursor,employees is a table
emp_ref_cur ref_cur_type;
emp_rec employees%ROWTYPE;
BEGIN
OPEN emp_ref_cur FOR 'SELECT * FROM employees';
LOOP
FETCH emp_ref_cur INTO emp_rec;
EXIT WHEN emp_ref_cur%NOTFOUND;
END lOOP;
END;
以下是具有强类型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游标呢
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 cursor变量和查询之间的约定。当我们认为动态SQL语句可以从UerthTabyStudio查询中组装时,更容易理解为什么不能这样做。p> 另一种可能性是声明并定义记录类型对象作为查询结果的容器。如果查询是一个联接查询,从多个联接表返回列,那么这可能很有用
SQL> create or replace procedure p1 is
/* Declare you destination data structure row container */
TYPE TestRecTyp IS RECORD (
deptno varchar(50),
ename varchar(50),
job varchar(50)
);
/* Define an instance of the record type */
testrec TestRecTyp;
type dept_rc is ref cursor; /*return dept%rowtype;*/
my_ref_cursor dept_rc;
begin
open my_ref_cursor for 'select deptno,ename,job from emp';
LOOP
FETCH my_ref_cursor INTO testrec;
EXIT WHEN my_ref_cursor%NOTFOUND;
/* Do some operations with testrec*/
END LOOP;
end;
注意:您可以在动态构造的SQL查询语句上使用上述技术,方法是用变量(如v_SQL)替换“select deptno,ename,job from emp”,并在过程主体内用SQL语句更新此变量。不允许为动态SQL打开强类型的ref游标,因为oracle引擎无法检查动态sql的结构是否与ref游标的返回类型的结构匹配