需要帮助理解 Cursor for loop
Need help understanding Cursor for loop
I am trying to write a code for every stock value that is or more
add a "*" in the STK_FLAG column. my error repots are: Error report -
ORA-06550: line 15, column 21: PLS-00201: identifier 'STK_FLG' must be
declared ORA-06550: line 15, column 5: PL/SQL: SQL Statement ignored
ORA-06550: line 23, column 7: PL/SQL: ORA-00904: "STK_FLG": invalid
identifier ORA-06550: line 17, column 5: PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Blockquote
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;
/
您没有声明游标变量(因此您无法放置游标返回的值)。不要将其命名为列名;使用前缀,例如 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;
/
为什么要使用 pl/sql 匿名块?即使对包含在 pl/sql 中的功能有“外部”要求,为什么还要使用游标和循环?使用 可能 可以的代码(来自@Littlefoot),您检索满足您条件的单个列,迭代结果记录集以获取该列,但不对其进行任何操作,并更新单个行在循环的每次迭代中都有一个文字值。 SQL 设计用于一次处理整组行。您的处理可以在 单个更新 语句中完成。假设有一个 pl/sql 块的外部要求,您的代码将减少为:
BEGIN
UPDATE mm_movie
SET stk_flag = '*'
WHERE movie_value * movie_qty >= 75;
COMMIT;
END;
拿走:在使用SQL时停止考虑迭代(循环)。而是考虑要处理的所有对象的共性(集合)。以不同的方式看待问题及其相应的解决方案。习惯这种思维方式需要一些时间,但从长远来看,运行 您的 SQL 和程序将因此而大大改进。无论是性能还是清晰度。
I am trying to write a code for every stock value that is or more add a "*" in the STK_FLAG column. my error repots are: Error report -
ORA-06550: line 15, column 21: PLS-00201: identifier 'STK_FLG' must be declared ORA-06550: line 15, column 5: PL/SQL: SQL Statement ignored ORA-06550: line 23, column 7: PL/SQL: ORA-00904: "STK_FLG": invalid identifier ORA-06550: line 17, column 5: PL/SQL: SQL Statement ignored 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. *Action:
Blockquote
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;
/
您没有声明游标变量(因此您无法放置游标返回的值)。不要将其命名为列名;使用前缀,例如 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;
/
为什么要使用 pl/sql 匿名块?即使对包含在 pl/sql 中的功能有“外部”要求,为什么还要使用游标和循环?使用 可能 可以的代码(来自@Littlefoot),您检索满足您条件的单个列,迭代结果记录集以获取该列,但不对其进行任何操作,并更新单个行在循环的每次迭代中都有一个文字值。 SQL 设计用于一次处理整组行。您的处理可以在 单个更新 语句中完成。假设有一个 pl/sql 块的外部要求,您的代码将减少为:
BEGIN
UPDATE mm_movie
SET stk_flag = '*'
WHERE movie_value * movie_qty >= 75;
COMMIT;
END;
拿走:在使用SQL时停止考虑迭代(循环)。而是考虑要处理的所有对象的共性(集合)。以不同的方式看待问题及其相应的解决方案。习惯这种思维方式需要一些时间,但从长远来看,运行 您的 SQL 和程序将因此而大大改进。无论是性能还是清晰度。