【问题标题】:How to create cursor inside procedure body in plsql如何在plsql中的过程主体内创建游标
【发布时间】:2012-08-22 20:33:37
【问题描述】:

我想在过程主体内动态创建 游标 我还必须使用 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循环吗?

【问题讨论】:

    标签: sql oracle plsql plsqldeveloper


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您不能将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;
      

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

      【讨论】:

      • 是的,你是对的,我简化了问题的代码。我理解在这种情况下我们不能使用 for 循环
      【解决方案3】:

      不能在游标 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;
      /
      

      【讨论】:

      • 我认为它是 about 程序的好选择。它只是我的代码
      • 如果我需要在循环内创建多个光标怎么办?
      猜你喜欢
      • 2018-01-02
      • 2020-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-24
      • 1970-01-01
      相关资源
      最近更新 更多