提取序列 <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 / rollbackRollback 使当前光标无效。无论如何,您都应该在 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> 回滚的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01002: 提取乱序

ORA-01002: 提取乱序

ORA-01002: 提取过程中的顺序不正确

ListAgg() ORA-01002: 提取乱序

pl/sql 存储函数 ora-01002 无序获取 SIMPLE

perl 多fasta文件匹配,并提取匹配文件第一条序列