使用回滚/提交关闭所有游标,如何克服
Posted
技术标签:
【中文标题】使用回滚/提交关闭所有游标,如何克服【英文标题】:Using roolback/commit colses all cursor, how to over come 【发布时间】:2016-05-23 06:54:29 【问题描述】:我有 PL/SQL 代码,其中我正在执行插入到表 1 并根据某些条件从表 2 中删除,如果删除成功,则提交所有上述语句并插入表 3,状态为“cond_true”else 回滚所有上述事务并插入 table3 'cond_false' 。如果在此代码中使用了提交和回滚,它将关闭打开的游标,并且必须再次为每个游标重新迭代,否则失败且没有游标打开状态。
OPEN cursor1;
Loop
fetch cursor1 into tbls;
exit when cursor1%notfound;
execute immediate INSERT INTO table1 SELECT * FROM table2;
-- commit only if below condition is true else rollback;
BEGIN
IF some_condition THEN
-- this condition will become true only after the above insert is executed successfully for all rows
execute immediate DELETE FROM table2 where some_condition2;
INSERT INTO table3 values('contition_true');
-- commit;
ELSE
INSERT INTO table3 values('contition_false');
--- first rollback the first insert and then commit only this statement;
END IF;
END;
END LOOP;
close cursor1;
【问题讨论】:
是什么让您认为光标在提交/回滚时关闭?另外,在这个特定示例中光标的意义何在?您没有引用循环内的光标。 在 oracle 回滚和提交中,关闭所有打开的游标。在上述情况下,游标包含 table1 和 table2 的表名 【参考方案1】:我不确定提交/回滚关闭光标是什么意思。你说的是哪个光标?您正在循环的光标,还是循环内的删除/插入语句?
提交/回滚将关闭事务,但不会关闭游标。如果是这种情况,以下代码在第二次循环光标时会出错,但您会注意到它不会:
begin
for rec in (select level lvl from dual connect by level <= 5)
loop
dbms_output.put_line('lvl = '||rec.lvl);
commit;
end loop;
end;
/
lvl = 1
lvl = 2
lvl = 3
lvl = 4
lvl = 5
也许您在谈论通过提交获取?如果是这样,请查看this AskTom question。
或者你的光标是FOR UPDATE
?如果是这样,那么执行提交将释放锁并关闭游标。
就目前情况而言,我在您的示例中看不到任何证据表明您根本需要一个游标循环(或者为什么您需要执行立即语句)。循环内部发生的事情与生成它的光标之间似乎没有联系。如果我是你,我会尝试使用一系列基于静态集的删除/插入来重写整个内容,而不是逐行执行所有操作。
【讨论】:
感谢 Boneist,for 循环将代替光标循环工作。正如我所说,上面给出的代码是一个大型动态过程的示例,它迭代了多组表并且具有不同的结构;所以不能使用静态语句。光标有表名和列名。以上是关于使用回滚/提交关闭所有游标,如何克服的主要内容,如果未能解决你的问题,请参考以下文章