我想在程序体内动态创建光标,我还必须使用 for loop 而不是代码。我做了动态光标,但我不能使用for循环。
PROCEDURE myprocedure
AS
LV_TEST_CUR SYS_REFCURSOR;
LV_QUERY VARCHAR2(200);
LV_DATE DATE;
BEGIN
LV_QUERY:='select sysdate as mydate from dual';
OPEN LV_TEST_CUR FOR LV_QUERY;
/*FOR CUR_VAR IN LV_TEST_CUR
LOOP
dbms_output.put_line(CUR_VAR.mydate);
end LOOP;
*/
LOOP
FETCH LV_TEST_CUR INTO LV_DATE;
EXIT
WHEN LV_TEST_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_DATE);
END LOOP;
CLOSE LV_TEST_CUR;
END myprocedure;
如果我使用注释代码(for循环),我会收到错误
PLS-00221:不是程序或未定义。
是否可以在动态游标中使用for循环?
答案 0 :(得分:6)
您无法在游标FOR循环中引用游标变量
但您可以直接使用选择参数:
create or replace PROCEDURE myprocedure
AS
LV_TEST_CUR SYS_REFCURSOR;
LV_QUERY VARCHAR2(200);
LV_DATE DATE;
BEGIN
FOR CUR_VAR IN (select sysdate as mydate from dual)
LOOP
dbms_output.put_line(CUR_VAR.mydate);
end LOOP;
END myprocedure;
/
答案 1 :(得分:1)
您不能将FOR <row> IN <cursor> LOOP
语法与动态SQL一起使用;请参阅the example in the documentation,其中显示了当代码被注释掉时您正在使用的方法。
你的例子根本不需要是动态的,但我认为你只是简化了这个问题。如果它有一个占位符,则无处可设置其值。如果你有:
LV_QUERY:='select sysdate - :days as mydate from dual';
FOR CUR_VAR IN LV_TEST_CUR LOOP
dbms_output.put_line(CUR_VAR.mydate);
END LOOP;
...然后FOR ... IN ...
版本无法在任何地方为days
占位符分配值。您必须使用动态OPEN
来执行此操作:
LV_QUERY:='select sysdate - :days as mydate from dual';
-- pass '1' as the bind variable
OPEN LV_TEST_CUR FOR LV_QUERY USING 1;
LOOP
FETCH LV_TEST_CUR INTO LV_DATE;
EXIT WHEN LV_TEST_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_DATE);
END LOOP;
CLOSE LV_TEST_CUR;
当然,您可能不需要占位符,只是动态构建查询字符串,但限制仍适用。
答案 2 :(得分:0)
据我所知,你不能使用带有游标变量的FOR循环或“ref cursor”。 FOR循环仅用于硬编码的SQL语句或游标 请参阅有关游标变量限制here的部分,其中明确指出“...您无法在游标FOR循环中引用游标变量”。