2010-05-26 18 views
0

我們在Oracle中有一個使用global temporary tables的存儲過程。在我們大多數其他存儲過程中,我們首先要從全局臨時表中刪除數據。但是,在少數存儲過程中,我們沒有delete's從Oracle中的不同會話獲取數據的全局臨時表

除了添加刪除語句之外是否還有其他選項?在SP運行時,服務器端可以做些什麼來強制刪除這些臨時表中的數據?

的GTT與ON COMMIT PRESERVE ROWS;

回答

2

的定義,我認爲您的標題有誤導之嫌:問題不在於「從不同的會話獲取數據」,它是重複使用同一個會話。終止會話始終刷新一個臨時表:

SQL> conn apc 
Enter password: 
Connected. 

SQL> create global temporary table tmp_23 (username varchar2(30)) 
    2 on commit preserve rows 
    3/

Table created. 

SQL> insert into tmp_23 values (user) 
    2/

1 row created. 

SQL> commit 
    2/

Commit complete. 

SQL> select * from tmp_23 
    2/

USERNAME 
------------------------------ 
APC 

SQL> conn apc 
Enter password: 
Connected. 
SQL> select * from tmp_23 
    2/

no rows selected 

SQL> 

從會話中有沒有辦法沖洗具有PRESERVE ROWS除非截斷刪除臨時表。無法以您建議的方式註釋存儲過程。所以我擔心,如果您在描述時遇到問題,則必須咬緊牙關,然後將DELETE(或TRUNCATE)調用添加到您的過程中。或者用DELETE ROWS定義表格;但這可能不適合你的處理。

順便說一句,它似乎是你使用臨時表相當沉重。這在Oracle系統中並不常見,因爲臨時表是相對昂貴的對象(所有寫入磁盤的對象),並且通常有更高效的方法來處理事情:在PL/SQL集合中緩存數據或僅使用SQL。來自非Oracle背景的開發人員(特別是SQL Server)過度使用臨時表是常見的,因爲他們習慣於這種工作方式。

+0

感謝您的詳細解釋。我們與應用服務器的連接只有8個(我們的用戶基數很大),所以連接池讓同一個會話過度使用。我認爲增加應用程序服務器連接將降低像這樣的問題的可能性,但在安全的一方總是有好處刪除 – Omnipresent 2010-05-26 17:34:44

+0

@Omnipresent - 是的,我想知道你是否使用連接池。當其他應用程序是無狀態的時,數據庫中狀態的持久性可能是一個真正的問題。 – APC 2010-05-26 17:57:22

+0

來自您的經驗什麼是擺脫臨時表的最佳方式。我們只是轉換爲oracle,並正在密集使用它們。你提到集合,我對Oracle連接不太熟悉,但是遊標呢?遊標可以獲得與集合相同的好處。 – Omnipresent 2010-05-26 18:06:55