5

我想在过程主体内动态创建光标,我也必须使用for 循环而不是下面的代码。我做了动态光标,但我不能使用 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 循环?

4

3 回答 3

6

您不能在游标 FOR 循环中引用游标变量

但您可以直接使用 select 语句:

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;
/
于 2012-08-28T11:06:05.963 回答
1

您不能将FOR <row> IN <cursor> LOOP语法与动态 SQL 一起使用;请参阅文档中的示例,该示例显示了无论如何注释掉该代码时您正在使用的方法。

你的例子根本不需要是动态的,但我假设你只是为这个问题简化了它。如果它有一个占位符,那么将无处可设置其值。如果你有:

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;

当然,您可能不需要占位符,只是动态构建查询字符串,但限制仍然适用。

于 2012-08-28T11:03:50.290 回答
0

据我所知,您不能将 FOR 循环与游标变量或“引用游标”一起使用。FOR 循环仅用于硬编码的 SQL 语句或游标。请参阅此处
有关游标变量限制的部分,其中明确指出“......您不能在游标 FOR 循环中引用游标变量”。

于 2012-08-28T11:01:06.297 回答