在存储过程中的删除语句后使用游标[重复]

Posted

技术标签:

【中文标题】在存储过程中的删除语句后使用游标[重复]【英文标题】:Using cursor after a delete statement in a stored procedure [duplicate] 【发布时间】:2012-11-23 06:56:27 【问题描述】:

可能重复:Oracle Accessing updated records during the same transaction

我有一个有点像这样的 Oracle 存储过程(实际 sql 不同)

CREATE OR REPLACE PROCEDURE mysp
IS
v_copied_row table%ROWTYPE ;

 CURSOR p_copied_rows IS
 select *
 from table ;

BEGIN
  delete from table
where <some condition>

OPEN p_copied_rows ;
LOOP
FETCH p_copied_rows into v_copied_rows ;
<do something with fetched row>
END LOOP
close p_copied_rows;
END;

理想情况下,我希望删除的行不应该是我从游标中获取的结果集的一部分,但那些是。

我是 Oracle 新手,想了解我是否在这里做错了什么?

附:我必须使用游标来处理一些复杂的事情,所以用 SQL 替换游标不是一种选择。

【问题讨论】:

我的错。在运行上述程序时,我错过了一个声明。版主可以删除/关闭此帖 【参考方案1】:

如果您的实际代码与您发布的代码匹配,则光标不会返回您删除的行

如果我创建一个有 100 行的表

SQL> ed
Wrote file afiedt.buf

  1  create table foo
  2  as
  3  select level col1
  4    from dual
  5* connect by level <= 100
SQL> /

Table created.

然后创建一个 PL/SQL 块来复制您发布的内容,删除 98 行,打开的游标将仅返回 2 行

SQL> select count(*) from foo;

  COUNT(*)
----------
       100

SQL> declare
  2    cursor non_deleted_rows
  3        is select *
  4             from foo;
  5    l_rec foo%rowtype;
  6  begin
  7    delete from foo
  8     where col1 <= 98;
  9
 10    open non_deleted_rows;
 11    loop
 12      fetch non_deleted_rows into l_rec;
 13      exit when non_deleted_rows%notfound;
 14
 15      dbms_output.put_line( l_rec.col1 );
 16    end loop;
 17  end;
 18  /
99
100

PL/SQL procedure successfully completed.

现在,如果您在发出DELETE 之前打开游标,游标将返回已删除的行。也许在您的实际代码中,OPEN 语句位于 DELETE 之前。

【讨论】:

以上是关于在存储过程中的删除语句后使用游标[重复]的主要内容,如果未能解决你的问题,请参考以下文章

创建游标的查询语句直接在mysql中可以运行,但是用存储过程的方式后我的游标查询不到数据 (附图)

存储过程(Stored Procedure)与游标(Cursor)

MySQL存储过程和游标

MySQL数据库编程02

MySQL 存储过程,获取使用游标查询的结果集

MySQL游标存储过程条件显示重复记录