提取序列 <ora-01002> 回滚
Posted
技术标签:
【中文标题】提取序列 <ora-01002> 回滚【英文标题】:Fetch Out of sequence <ora-01002> Rollback 【发布时间】:2017-07-06 19:03:06 【问题描述】:今天我遇到了“FETCH OUT OF SEQUENCE”ORA-01002。我做了很多研究,我开始明白这很常见。
-
当我们已经关闭游标时尝试获取。
用于更新和提交。
如果处理成功,我的要求是每 500 条记录提交一次,如果出现任何问题,则回滚获取的 500 条记录。
其中任何一个我都没有做过。我还发现由于 ROLLBACK 发生了乱序提取;
我还缩小了实际发生的时间。仅当第一组记录发生回滚时才会发生这种情况。
loop
Fetch c1 bulk collect into type1 limit 500;
exit when type1.count=0;
forall in i..type1.count save exceptions
insert into the table.
do something.....
the computation goes on;
Commit;
exception when others then
for i in 1..sql%bulk_exceptions loop
Do somthing...
end loop;
rollback; => Fetch out of seq happens here...
end loop;
仅当前 500 条记录失败并且我发出回滚命令时才会发生乱序提取。当前 500 条记录被提交并且接下来的 500 条记录被回滚时,它不会给出 ora-01002。
它这样做的任何原因。请建议是否有任何方法可以避免 ora-01002 错误。
很抱歉,由于公司政策,无法在此处发布编码。但是上面给出的伪代码是如何编码的。
附加信息-> 如果我以这种方式执行程序,那么我不会收到错误“ORA-01002”。
loop
Fetch c1 bulk collect into type1 limit 500;
exit when type1.count=0;
COMMIT; => IF I ADD COMMIT HERE ORA-01002 doesnt appear.
forall in i..type1.count save exceptions
insert into the table.
do something.....
the computation goes on;
Commit;
exception when others then
for i in 1..sql%bulk_exceptions loop
Do somthing...
end loop;
rollback; => Fetch out of seq happens here...
结束循环;
【问题讨论】:
【参考方案1】:当您以这种方式处理记录时,您不应该在处理过程中出现这样的 commit
/ rollback
。 Rollback
使当前光标无效。无论如何,您都应该在 500 条记录之后提交,并处理异常。
一旦您回滚,Oracle 就无法回忆其光标所在的位置。
就像this example 的语句 7 一样,您应该处理 FORALL
的单一异常以防万一
--- declare exception
failure_in_forall EXCEPTION;
PRAGMA EXCEPTION_INIT (failure_in_forall, -24381);
...
-- handle it
EXCEPTION
WHEN failure_in_forall
...
然后您的好的记录将被处理和提交,而不好的记录将在以后进行审查和处理
【讨论】:
@J Chomel 非常感谢。我知道光标由于回滚而失效。但我仍然有疑问。只有当我用于更新时,回滚才会无效。如果我错了,请纠正我。谢谢 另外,当我在将批量收集到类型之前提交时,然后回滚,问题就消失了。为什么会这样? 另外我不能使用 PRAGMA EXCEPTION_INIT 进行正常循环,如果我错了,请纠正我。 @Premakumari,PRAGMA 必须位于您的DECLARE
部分;我不确定问题应该发生在哪里,但在我看来,像你一开始那样进行回滚是不正确的。很高兴知道您找到了解决方法。但我无法解释为什么会这样。可能它是允许以下回滚所需的新事务的开始。
我还检查了光标是否关闭。但令我惊讶的是,光标并没有失效或关闭。它处于打开状态。这种奇怪行为的原因可能是什么?以上是关于提取序列 <ora-01002> 回滚的主要内容,如果未能解决你的问题,请参考以下文章