有个疑问请各位大侠帮忙解释一下。
procedure a ,procedure b在a过程中用有如下语句
for elements in (select * from a)
loop
b(a.xx);//b操作的表跟a表完全无关
end loop;
当这个cursor取到的第一条记录导致b过程rollback的话就会导致cursor取第二条记录的时候异常退出,报错信息是ORA-01002:fetch out of sequence.
如果b处理cursor的第一条记录正常结束的话,再遇到rollback的情况就不会报错,正常执行。
procedure a ,procedure b在a过程中用有如下语句
for elements in (select * from a)
loop
b(a.xx);//b操作的表跟a表完全无关
end loop;
当这个cursor取到的第一条记录导致b过程rollback的话就会导致cursor取第二条记录的时候异常退出,报错信息是ORA-01002:fetch out of sequence.
如果b处理cursor的第一条记录正常结束的话,再遇到rollback的情况就不会报错,正常执行。
解决方案 »
- 怎样用自己的电脑连接公司的数据库
- Oracle 11g R2 怎么才能登录到控制台界面?
- 两个表进行比较,表结构相同,比较数据是否相同,应该如何写?谢谢
- Environment variable ORACLE_UNQNAME not defined.
- 关于单独存放BLOB文件表空间的问题
- 如何使用"INSERT INTO"将ORACLE中的表插到SQL SERVER数据库中
- 怎么实时的删除重复的纪录
- 一个SQL语句问题
- ORACLE8i,9i,10g的安装问题(本问题可达350分)
- current redo异常恢复
- oracle层次查询,挑战高手!!!
- 关于一个Oracle存储过程问题~~~在线等~~
proc1对表记录做初始化,proc2按照业务逻辑修改表中的字段值,过程中均没有显式提交。两个过程单独执行均不会报错,但同时执行就会出错。错误号:ORA-01002: fetch out of sequence首先查看官方文档对ORA-01002错误号的解释:
Cause: This error means that a fetch has been attempted from a cursor which is no longer valid. Note that a PL/SQL cursor loop implicitly does fetches, and thus may also cause this error. There are a number of possible causes for this error, including: 1) Fetching from a cursor after the last row has been retrieved and the ORA-1403 error returned. 2) If the cursor has been opened with the FOR UPDATE clause, fetching after a COMMIT has been issued will return the error. 3) Rebinding any placeholders in the SQL statement, then issuing a fetch before reexecuting the statement.
Action: 1) Do not issue a fetch statement after the last row has been retrieved - there are no more rows to fetch. 2) Do not issue a COMMIT inside a fetch loop for a cursor that has been opened FOR UPDATE. 3) Reexecute the statement after rebinding, then attempt to fetch again.
由于proc1非常简单,就是几个update语句,proc2隐式声明了cursor循环更新,逻辑比较复杂,因此初步分析问题极可能是出在proc2的逻辑处理上,重点关注proc2。
由于pl/sql并没有提供单步调试的功能,为了清晰每步执行的状况,在相关重要位置通过dbms_output打印更新行ID等,并在适当位置加上exception捕获可能的错误。重新单独执行proc2确实捕获到了几个错误,都是:ORA-01401: inserted value too large for column根据打印输出的行号到原始表中查询了一下,确实是字段超长,重新看了看proc2的执行逻辑,由于其中对于更新操作有exception做处理,如果更新出错会继续跳到下一条,所以此处即使出错应该没关系,过程仍然会继续向下执行,这个错误应该不是造成ora-01002的主要原因。手动 rollback,然后重新同时执行proc1,proc2,这次出错,但这次只报了一次ORA-01401,接着就是ORA-01002,看起来仿佛又跟ora-01401有关系了,重点看看出错地方的代码,发现exception之后,执行了一个rollback,这个,不管是从业务逻辑,还是从程序逻辑上显然都是不合理的,去掉它之后再执行,成功!再回过头来看一看,虽然proc2中ora-1401并非造成ora-01002的主因,但如果proc2执行过程中不报错,那么自然也不会执行rollback,造成事务回滚,从而触发ora-1002错误,这也解释了为什么之前都执行的好好的,没有做任何改动的情况下忽然出现了错误。如果proc2一直正确执行的话,这个错误肯定就不会暴露出来。问题的主要原因还是因为在proc2执行出错时,执行了rollback,因此将rollback注释掉,重新编译proc2,再次执行,一切正常,问题解决!能commit或rollback的。
如果cursor的第一条记录使b过程正常执行的话,即使第二条记录会导致b中出现rollback,a中的loop也不会异常。
出现异常的情况只有是在cursor取到的第一条记录就导致b过程rollback的时候。
每处理一条记录都会commit的。
代码也很简单,b过程就是使用了cursor中提供一个值。
b过程进行insert操作? 那又是怎么进行rollback的呢?
如果cursor取到的第一条记录导致b过程rollback的话,cursor就会关闭。
如果cursor取到的第一条记录b正常处理完毕的话,即使后面的记录导致b过程rollback,a过程中的cursor也不会关闭。b过程是使用了cursor提供的值,update和insert的其他的表。