當我們定義了一個很複雜的cursor,這個cursor需要執行很長時間,在這個cursor執行的過程中,其它使用者又修改了該cursor所引用的表的資料時,cursor得到的是修改前還是修改後的資料呢?
答案是cursor得到的始終是cursor在open時的資料,接下來我們將通過一個小實驗來驗證。
首先,session1執行以下匿名塊,該匿名塊通過cursor取得t1表的所有資料,不過在open cursor後將暫停30秒,在這30秒中我們將在session2中刪除t1表的所有資料:
- DECLARE
- CURSOR c IS
- SELECT deptno
- ,dname
- ,loc
- FROM t1;
- TYPE dept_tab IS TABLE OF c%ROWTYPE;
- l_depts dept_tab;
- BEGIN
- dbms_output.put_line('opening c: ' ||
- to_char(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
- OPEN c;
- dbms_lock.sleep(30);
- dbms_output.put_line('after sleep: ' ||
- to_char(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
-
- FETCH c BULK COLLECT
- INTO l_depts;
- CLOSE c;
-
- FOR i IN l_depts.FIRST .. l_depts.LAST
- LOOP
- dbms_output.put_line(l_depts(i).deptno || ', ' || l_depts(i)
- .dname || ', ' || l_depts(i).loc);
- END LOOP;
- END;
-
- 第二步,session2執行以下語句:
- 22:35:21 SQL> select * from t1;
-
- DEPTNO DNAME LOC
- ------ -------------- -------------
- 10 ACCOUNTING NEW YORK
- 20 RESEARCH DALLAS
- 30 SALES CHICAGO
- 40 OPERATIONS BOSTON
-
- 22:35:29 SQL> delete from t1;
-
- 4 rows deleted
-
- 22:35:33 SQL> commit;
-
- Commit complete
-
- 22:35:35 SQL> select * from t1;
-
- DEPTNO DNAME LOC
- ------ -------------- -------------
-
- 22:35:38 SQL>
-
- 最後,觀察session1的輸出:
- opening c: 2011-10-26 22:35:25
- after sleep: 2011-10-26 22:35:55
- 10, ACCOUNTING, NEW YORK
- 20, RESEARCH, DALLAS
- 30, SALES, CHICAGO
- 40, OPERATIONS, BOSTON
-
- 由於在22:35:25我們就已經開啟了遊標,所以結果依然能輸出t1表的所有資料,儘管在22:35:35之前我們已經刪除了t1表的所有資料並提交,而cursor取資料(fetch)發生在22:35:55之後。
-
- ref:
- 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.
- http://download.Oracle.com/docs/cd/B19306_01/appdev.102/b14261/open_statement.htm#i35173