ORA-01002 “fetch out of sequence”关于cursor的一个bug

简介:     今天发现一个PLSQL脚本报ORA-01002和ORA-06512: ERROR at line 1:ORA-01002: fetch out of sequenceORA-06512: at line 8     原来,脚本里包含两个表的两个cursor,然后分别对每个表打开cursor然后对此表做一些dml,每隔若干行rollback(这是因为此PLSQL脚本还在测试阶段,所以需要rollback)。

    今天发现一个PLSQL脚本报ORA-01002和ORA-06512:

ERROR at line 1:
ORA-01002: fetch out of sequence
ORA-06512: at line 8

    原来,脚本里包含两个表的两个cursor,然后分别对每个表打开cursor然后对此表做一些dml,每隔若干行rollback(这是因为此PLSQL脚本还在测试阶段,所以需要rollback)。

    然而,问题就出在,对表A作为dml后,在循环完成的最后没有写“rollback”,这就导致了对表A的一些dml在脚本打开表B的cursor前,并没有被rollback,于是报此错。

    举个简单的例子,例如cursor取出表A的1004行,然后每隔100行rollback一次,那么最后还有对最后4行的dml没有被rollback,接着打开另一个cursor时报错。

这个错,跟Bug 3039457: PL/SQL: FETCH FAILS WITH ORA-1002 AFTER ROLLBACK有一定联系。

    之所以,我提出这个错误号01002,是因为OERR ORA 1002的三个解释中都不包含这个bug。

 oerr ora 1002
01002, 00000, "fetch out of sequence"
// *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.

    下面做一个很简单的实验解释这个bug。

    准备脚本test1.sql:

DECLARE
cursor c1 is select rowid
               from test1
              where ROWNUM <= 50000;
cnt number(38);
begin
   cnt := 0;
   for c1rec in c1 loop
      delete from test1
       where rowid = c1rec.rowid;

      cnt := cnt + 1;
      if mod(cnt, 77) = 0 then
        rollback;
      end if;
   end loop;
   rollback;
end;
/

    如上,我每隔77行rollback一次,对于一共50000行数据,肯定最后会剩下一些delete没有被rollback。如果我接着再run test1.sql,就会触发这个bug:

SQL> @test1

PL/SQL procedure successfully completed.

SQL> @test1
DECLARE
*
ERROR at line 1:
ORA-01002: fetch out of sequence
ORA-06512: at line 8


SQL> @test1

PL/SQL procedure successfully completed.

SQL> @test1
DECLARE
*
ERROR at line 1:
ORA-01002: fetch out of sequence
ORA-06512: at line 8

    解决方法很简单,就是在test1.sql的最后加上一句rollback就行了。

SQL> @test1

PL/SQL procedure successfully completed.

SQL> rollback;

Rollback complete.

SQL> @test1

PL/SQL procedure successfully completed.

目录
相关文章
|
Oracle 关系型数据库 数据库
Oracle查询优化-限制返回行数
【1月更文挑战第1天】【1月更文挑战第2篇】Oracle数据库是常用的数据库之一尤其数据量较大时很友好。但当一个查询结果太大时,Oracle很容易将内存和 CPU 规模炸裂而导致异常,限制查询结果返回的行数是很有必要的。有的时候又不是进行分页查询的情况下,就需要灵活运用ROWNUM。
825 0
|
存储 SQL Oracle
Oracle使用expdp/impdp实现全库导入导出的整体流程
Oracle的全库导入,首先一点必须先创建数据库,创建了数据库,才能往该数据库导入所有数据。相对来说,使用Oracle进行数据导入导出还很有些“麻烦”的,大多数资料上来就是......
12467 0
Oracle使用expdp/impdp实现全库导入导出的整体流程
|
9月前
|
SQL 存储 人工智能
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
Vanna 是一个开源的 Python RAG(Retrieval-Augmented Generation)框架,能够基于大型语言模型(LLMs)为数据库生成精确的 SQL 查询。Vanna 支持多种 LLMs、向量数据库和 SQL 数据库,提供高准确性查询,同时确保数据库内容安全私密,不外泄。
1384 7
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
|
11月前
|
机器学习/深度学习 搜索推荐 语音技术
前沿探索:融合语音克隆与TTS技术实现个性化语音助手
【10月更文挑战第20天】随着人工智能技术的迅猛发展,语音助手已经成为我们日常生活不可或缺的一部分。然而,传统的语音助手往往缺乏个性化元素,无法充分满足用户的独特需求。作为技术专家或研究人员,我一直致力于探索如何将语音克隆(Voice Cloning)技术与文本到语音(Text-to-Speech, TTS)技术相结合,创造出更加个性化且自然流畅的语音助手。本文将分享我的研究成果和个人观点,希望能为这一领域的未来发展提供一些启示。
435 2
前沿探索:融合语音克隆与TTS技术实现个性化语音助手
|
11月前
|
Linux Docker 容器
Centos安装docker(linux安装docker)——超详细小白可操作手把手教程,包好用!!!
本篇博客重在讲解Centos安装docker,经博主多次在不同服务器上测试,极其的稳定,尤其是阿里的服务器,一路复制命令畅通无阻。
18036 5
Centos安装docker(linux安装docker)——超详细小白可操作手把手教程,包好用!!!
|
NoSQL 前端开发 Redis
Windows 下安装和配置 Redis (图文教程)
Windows 下安装和配置 Redis (图文教程)
|
数据库 数据库管理 索引
主键和唯一键有什么区别?
【8月更文挑战第1天】
782 6
主键和唯一键有什么区别?
|
SQL Oracle 关系型数据库
Oracle-Materialized View解读
Oracle-Materialized View解读
1020 0
|
XML 前端开发 Java
SpringMVC中<mvc:annotation-driven/>标签原理与实践详解
SpringMVC中<mvc:annotation-driven/>标签原理与实践详解
329 0