需要帮助理解 Cursor for loop

Posted

技术标签:

【中文标题】需要帮助理解 Cursor for loop【英文标题】:Need help understanding Cursor for loop 【发布时间】:2021-03-31 03:03:08 【问题描述】:

我正在尝试为每个 75 美元或以上的股票价值编写代码 在 STK_FLAG 列中添加“*”。我的错误报告是:错误报告 -

ORA-06550:第 15 行,第 21 列:PLS-00201:标识符“STK_FLG”必须是 声明 ORA-06550:第 15 行,第 5 列:PL/SQL:SQL 语句被忽略 ORA-06550:第 23 行,第 7 列:PL/SQL:ORA-00904:“STK_FLG”:无效 标识符 ORA-06550:第 17 行,第 5 列:PL/SQL:忽略 SQL 语句 06550. 00000 - “第 %s 行,第 %s 列:\n%s” *原因:通常是 PL/SQL 编译错误。 *行动:

块引用

SET SERVEROUTPUT ON

DECLARE

CURSOR CURR
   IS
     SELECT STK_FLAG
     FROM MM_MOVIE
     WHERE MOVIE_VALUE * MOVIE_QTY >= 75
     FOR UPDATE;
BEGIN

OPEN CURR;
   
  LOOP

    FETCH CURR INTO STK_FLG;

    UPDATE

      MM_MOVIE

    SET

      STK_FLG= '*'

    WHERE

      CURRENT OF CURR;

    EXIT

  WHEN CURR%notfound;

  END LOOP;

  Commit;

   CLOSE CURR;
END;
/

【问题讨论】:

【参考方案1】:

您没有声明游标变量(因此您无法放置游标返回的值)。不要将其命名为列名;使用前缀,例如 v_l_ 或任何你想要的。

此外,在UPDATE 中,您引用了一个不存在的列。光标暗示它的名字是stk_flag,而不是stk_flg

因此,可能可以的代码是

DECLARE
   CURSOR curr IS
      SELECT stk_flag
        FROM mm_movie
       WHERE movie_value * movie_qty >= 75
      FOR UPDATE;

   l_stk_flag  mm_movie.stk_flag%TYPE;  --> this
BEGIN
   OPEN curr;

   LOOP
      FETCH curr INTO l_stk_flag;

      EXIT WHEN curr%NOTFOUND;

      UPDATE mm_movie
         SET stk_flag = '*'             --> this
       WHERE CURRENT OF curr;
   END LOOP;

   COMMIT;

   CLOSE curr;
END;
/

【讨论】:

非常感谢您的帮助和解释! @小脚【参考方案2】:

为什么要使用 pl/sql 匿名块?即使包装到 pl/sql 中的功能有“外部”需求,为什么还要使用游标和循环?使用可能可以的代码(来自@Littlefoot)检索满足条件的单个列,迭代获取该列的结果记录集,但不对其执行任何操作,并在每次迭代时更新一行带有文字值的循环。 SQL 旨在一次处理整组行。您的处理可以在 single update 语句中完成。假设对 pl/sql 块有外部要求,您的代码将简化为:

BEGIN
   UPDATE mm_movie
      SET stk_flag = '*'   
    WHERE movie_value * movie_qty >= 75;
    
   COMMIT;
END;   

带走:使用 SQL 时,请停止考虑迭代(循环)。而是考虑要处理的所有对象的共性(集合)。可以肯定的是,以不同的方式看待问题及其相应的解决方案。习惯这种思考方式需要一些时间,但从长远来看,您的 SQL 和过程会因此而大大改善。无论是性能还是清晰度。

【讨论】:

以上是关于需要帮助理解 Cursor for loop的主要内容,如果未能解决你的问题,请参考以下文章

我需要帮助理解这个 openMP 示例

执行 CURSOR 时的 PLSQL FOR 循环

sqlserver中怎样使用游标for循环

MONGODB [DEBUG] cursor.refresh() for cursor 7078636577051629992

MONGODB [DEBUG] cursor.refresh() for cursor 7078636577051629992

DB2 for z/OS:CURSOR FOR UPDATE 锁定行为