我有一个 PL/SQL 块,其中:
- 声明并初始化一个集合 (TABLE OF my_table.key%TYPE)。
- 使用 SYS_REFCURSOR 将键批量收集到集合中。
- 打印 lst.COUNT,显示 0。
- 运行 FORALL 循环根据收集的键更新 my_table 中的行。
- 打印 SQL%ROWCOUNT,意外地显示有 1 行已更新。
DECLARE
TYPE t_list IS TABLE OF my_table.key%TYPE;
lst t_list := t_list();
cur SYS_REFCURSOR;
var NUMBER; -- Holds sequence value
BEGIN
-- Assign sequence value
var := my_sequence.NEXTVAL;
-- Open and fetch cursor
OPEN cur FOR
SELECT key FROM my_table WHERE some_conditions;
FETCH cur BULK COLLECT INTO lst;
CLOSE cur;
-- Debug output
DBMS_OUTPUT.PUT_LINE('lst.COUNT: ' || lst.COUNT); -- Prints 0
-- FORALL update
FORALL I IN 1..lst.COUNT
UPDATE my_table
SET col = SYSDATE
WHERE key = lst(I)
AND status = 'A';
DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT: ' || SQL%ROWCOUNT); -- Prints 1
END;
观察与问题:
- lst.COUNT = 0,因此 FORALL 根本不应该执行。
- 但是,SQL%ROWCOUNT 显示更新了 1 行而不是 0 行。
- 如果我删除sequence.NEXTVAL分配,SQL%ROWCOUNT将正确显示0。
问题:
- 为什么即使 FORALL 没有执行,SQL%ROWCOUNT 也会显示 1?
- sequence.NEXTVAL 是否会以某种方式影响 SQL%ROWCOUNT?
- 如何确保 SQL%ROWCOUNT 仅正确反映 FORALL 更新?