【问题标题】:Need help understanding Cursor for loop需要帮助理解 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;
/
【问题讨论】:
标签:
oracle
plsql
cursor
oracle-sqldeveloper
【解决方案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 和过程会因此而大大改善。无论是性能还是清晰度。