Oracle PLSQL之cursor取得是open时的数据


当我们定义了一个很复杂的cursor,这个cursor需要执行很长时间,在这个cursor执行的过程中,其它用户又修改了该cursor所引用的表的数据时,cursor得到的是修改前还是修改后的数据呢? 

答案是cursor得到的始终是cursor在open时的数据,接下来我们将通过一个小实验来验证。

首先,session1执行以下匿名块,该匿名块通过cursor取得t1表的所有数据,不过在open cursor后将暂停30秒,在这30秒中我们将在session2中删除t1表的所有数据: 

  1. DECLARE  
  2.   CURSOR c IS  
  3.     SELECT deptno  
  4.           ,dname  
  5.           ,loc  
  6.       FROM t1;  
  7.   TYPE dept_tab IS TABLE OF c%ROWTYPE;  
  8.   l_depts dept_tab;  
  9. BEGIN  
  10.   dbms_output.put_line('opening c: ' ||  
  11.                        to_char(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));  
  12.   OPEN c;  
  13.   dbms_lock.sleep(30);  
  14.   dbms_output.put_line('after sleep: ' ||  
  15.                        to_char(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));  
  16.   
  17.   FETCH c BULK COLLECT  
  18.     INTO l_depts;  
  19.   CLOSE c;  
  20.   
  21.   FOR i IN l_depts.FIRST .. l_depts.LAST  
  22.   LOOP  
  23.     dbms_output.put_line(l_depts(i).deptno || ', ' || l_depts(i)  
  24.                          .dname || ', ' || l_depts(i).loc);  
  25.   END LOOP;  
  26. END;  
  27.   
  28. 第二步,session2执行以下语句:  
  29. 22:35:21 SQL> select * from t1;  
  30.    
  31. DEPTNO DNAME          LOC  
  32. ------ -------------- -------------   
  33.     10 ACCOUNTING     NEW YORK  
  34.     20 RESEARCH       DALLAS  
  35.     30 SALES          CHICAGO  
  36.     40 OPERATIONS     BOSTON  
  37.    
  38. 22:35:29 SQL> delete from t1;  
  39.    
  40. rows deleted  
  41.    
  42. 22:35:33 SQL> commit;  
  43.    
  44. Commit complete  
  45.    
  46. 22:35:35 SQL> select * from t1;  
  47.    
  48. DEPTNO DNAME          LOC  
  49. ------ -------------- -------------   
  50.    
  51. 22:35:38 SQL>   
  52.   
  53. 最后,观察session1的输出:  
  54. opening c: 2011-10-26 22:35:25  
  55. after sleep: 2011-10-26 22:35:55  
  56. 10, ACCOUNTING, NEW YORK  
  57. 20, RESEARCH, DALLAS  
  58. 30, SALES, CHICAGO  
  59. 40, OPERATIONS, BOSTON  
  60.   
  61. 由于在22:35:25我们就已经打开了游标,所以结果依然能输出t1表的所有数据,尽管在22:35:35之前我们已经删除了t1表的所有数据并提交,而cursor取数据(fetch)发生在22:35:55之后。  
  62.   
  63. ref:  
  64. The OPEN statement executes the query associated with a cursor. It allocates database resources to process the query and identifies the result set -- the rows that match the query conditions.   
  65. http://download.Oracle.com/docs/cd/B19306_01/appdev.102/b14261/open_statement.htm#i35173  

相关内容