数据库游标是否会捕捉到底层数据的更改?

11

关于游标(特别是Oracle游标)的一个问题。

假设我有一张名为“my_table”的表,它有两列,一个ID和一个名称。这个表有数百万行,但是名称列总是字符串“test”。

然后我运行这个PL/SQL脚本:

declare
 cursor cur is
  select t.id, t.name
    from my_table t
   order by 1;
 begin
   for cur_row in cur loop
     if (cur_row.name = 'test') then
        dbms_output.put_line('everything is fine!');
     else
        dbms_output.put_line('error error error!!!!!');
        exit;
     end if;
   end loop;
 end; 
 /

如果我在程序运行时执行以下SQL语句:

 update my_table 
   set name = 'error'
  where id = <max id>;
commit;

PL/SQL块中的光标是否会捕捉到该更改并打印出“错误错误错误”并退出?还是根本不会捕捉到更改...或者甚至允许更新my_table?

谢谢!


1
你有一些代码,为什么不运行它看看呢? - Dominic Rodger
1个回答

15

游标实际上运行了一条 SELECT 语句,然后让你迭代结果集,该结果集保留在快照中。因为已经获取了结果集,所以它不会受 UPDATE 语句的影响。(否则,每次前进游标时都需要重新运行查询!)

参见:

http://www.techonthenet.com/oracle/cursors/declare.php


7
尽管更新语句不会影响游标,但并非所有游标将访问的数据都已经预先获取到内存中。如果是这种情况,从游标获取第一行数据通常需要很长时间。实际情况是,游标选择的数据是在其打开时所对应的SCN(系统变化号)处的数据。“快照太旧”错误有时会导致长时间运行的查询失败。 - Tony Andrews
很好的澄清,Tony。谢谢。我会相应地更新我的答案。 - Sean McMains
对于SYBASE ASE,从15.7开始,您可以声明INSENSITIVE游标,它指定“独立于游标的数据更改对游标结果集不可见。如果您不指定此参数,则默认为semi_sensitive。您不能更新一个insensitive游标。” - eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接