示例一
-- Create table 三目錄監控存儲過程臨時表 create global temporary table L_DIAITEM_ERROR ( forgid NUMBER, --組織機構id forgname VARCHAR2(80), --組織機構名稱 nccw NUMBER, --名稱錯誤數 wdz NUMBER --未對照計數 ) on commit delete rows; --事務提交時,清空表數據 --插入一條數據 INSERT INTO L_DIAITEM_ERROR (nccw,wdz) SELECT 1,2 FROM DUAL; --查詢該表數據 SELECT * FROM L_DIAITEM_ERROR
示例二
第一步:創建臨時表
/** * 創建臨時指標表 */ CREATE GLOBAL TEMPORARY TABLE TAB_INDEX_TEMP(A_ID NUMBER,--一級指標ID A_INDEXNAME VARCHAR2(50), --一級指標名稱 TOTALWEIGHT NUMBER, --權重占比 B_ID NUMBER, --二級指標ID B_INDEXNAME VARCHAR2(200), ----二級指標名稱 INDEXSCORE NUMBER, --指標分值 COUNTER VARCHAR2(200), --計算方法 REMARK VARCHAR2(200)) ON COMMIT DELETE ROWS;/*事務提交時,清空臨時表數據*/
第二步:將數據插入臨時表
/*將數據批量插入臨時表*/ INSERT INTO TAB_INDEX_TEMP SELECT A.ID A_ID, A.INDEXNAME A_INDEXNAME, A.TOTALWEIGHT, B.ID B_ID, B.INDEXNAME B_INDEXNAME, B.INDEXSCORE, B.COUNTER, B.REMARK FROM INDEX_B B, INDEX_A A WHERE A.STATUS = 1 AND B.STATUS = 1 AND B.INDEXTYPE = 2 --二級指標 AND B.INDEXA_ID = A.ID ORDER BY B_ID;
第三步:查詢臨時表
說明:
執行插入語句后,如果沒有提交,執行查詢語句,該表有數據;
如果提交事務,執行查詢語句,清空數據;
臨時表一般和存儲過程一起使用。
詳細介紹
參考鏈接:http://www.cnblogs.com/vigarbuaa/archive/2012/06/04/2534797.html
在Oracle8i中,可以創建以下兩種臨時表:
(1)會話特有的臨時表
語法:
CREATE GLOBAL TEMPORARY <TABLE_NAME> (<column specification>) ON COMMIT PRESERVE ROWS;
(2)事務特有的臨時表
語法:
CREATE GLOBAL TEMPORARY <TABLE_NAME> (<column specification>) ON COMMIT DELETE ROWS;
舉例:
CREATE GLOBAL TEMPORARY TABLE MyTempTable
區別:
ON COMMIT DELETE ROWS 說明臨時表是事務指定,每次提交后ORACLE將截斷表(刪除全部行,清空表數據)
ON COMMIT PRESERVE ROWS 說明臨時表是會話指定,每次中斷會話ORACLE將截斷表(清空表數據)
作用域:
通過CREATE GLOBAL TEMPORARY TABLE命令創建一個臨時表,
對於事務類型的臨時表,數據只是在本事務期間存在;對於會話類型的臨時表,數據在本會話期間存在。
臨時表的特點:
可以對臨時表創建索引,視圖,觸發器,可以用export和import工具導入導出表的定義,但是不能導出數據。表的定義對所有的會話可見。
(1) 多用戶操作的獨立性:對於使用同一張臨時表的不同用戶,ORACLE都會分配一個獨立的 Temp Segment,這樣就避免了多個用戶在對同一張臨時表操作時發生交叉,從而保證了多個用戶操作的並發性和獨立性;
(2) 數據的臨時性:既然是臨時表,顧名思義,存放在該表中的數據是臨時性的。ORACLE根據你創建臨時表時指定的參數(On Commit Delete Rows / On Commit Preserve Rows),自動將數據TRUNCATE掉。
2020/04/18
應用場景:在oracle存儲過程中,使用臨時表返回數據游標。
會話指定:PRESERVE
在plsql中測試結果如下:
1.如果是會話指定:PRESERVE,存儲過程測試窗口運行一次后,未關閉該窗口的情況下,無法刪除該臨時表;(即使該提交的事務已經提交)
以存儲過程中往臨時表中插入數據為例,當存儲過程里沒有自動提交,且測試窗口也沒有手動提交時
2.點擊紅框左側按鈕執行幾次,數據就會插入幾次,即使沒有提交,只有關閉窗口時,該臨時表所對應的會話數據才會消失。
在javaWeb項目中調用該存儲過程,以上兩點也同樣適用,只有關閉程序,會話才算結束,臨時表數據才會被清空。
因此,在程序調用存儲過程時,不能使用會話指定:PRESERVE,數據庫會判定程序始終是同一會話,這樣的話,數據只會越查越多,根本不是我們想要的結果。
如果非得使用這種指定方式的話,需要在存儲過程調用該臨時表前清空該臨時表。
另外,不同會話之前的臨時表數據不是互通的,比如上圖所示,A會話里臨時表已經有很多數據,當你再打開一個測試窗口進行查詢時數據就不會有這么多了。
事物指定:DELETE
在plsql中測試結果如下:
1.在事務提交之前,無法刪除該臨時表;但事務提交后,就可以刪除啦。
2.當存儲過程沒有自動提交,需要手動提交時,在測試窗口查詢多少次,就會插入多少次,只有在提交事務后,該會話中臨時表的數據才會消失。
在javaWeb項目中調用該存儲過程,就與上面不同啦:
ibatis插件在執行SQL時會自動執行commit事務,所以,臨時表想什么時候刪就什么時候刪掉;
由於程序可以自動提交,所以查詢出來的數據永遠不存在重復插入這種情況。
另外,事務指定,會話之間也是獨立的,當在plsql中執行兩次后,該會話已經出現重復數據,此時,使用程序調用一次存儲過程,數據依舊不會出現重復的情況。
所以說,使用事務指定,會話之間的臨時表數據也是獨立的。
另外,事務指定還有一個特性就是:即使你沒有提交,直接關閉會話,臨時表的數據也會被清空。
最后說一點,當存儲過程要返回的數據是含有臨時表數據時,則使用事務指定的時候,對於臨時表進行新增或修改的操作都不能提交,因為一旦提交臨時表數據就會消失。
程序調用的時候也會報錯。