2010-04-23 35 views
2

我在創建腳本中使用選項刪除行時有一個全局臨時表(GTT)。我希望能夠讓不同的用戶在GTT中看到他們自己的數據,而不是其他人的會話的數據。這在我們的測試環境中完美運行。具有「On commit delete rows」的全局臨時表不包含任何數據

但是後來我部署了GTT作爲客戶端數據庫功能更新的一部分。客戶打電話給我感到不安和擔心,因爲GTT沒有任何數據,他們不知道爲什麼。

特別是,如果有人做:

insert into my_GTT (description) values ('Happy happy joy joy') 

數據庫會迴應:

1 row inserted. 

然而,如果相同的最終用戶嘗試:

select * from my_GTT 

該數據庫將作出迴應:

0 rows returned. 

此問題發生在客戶端網站上,我們無法在內部複製它。什麼可能導致這種行爲?

+0

什麼是「玩伴」 - 是另一個會話?你有沒有試過把表格改成ON COMMIT PRESERVE ROWS,只是爲了看看會發生什麼? – 2010-05-03 04:22:37

+0

「玩伴」是最終用戶。這個問題發生在客戶端,我們不能在內部重現它。此外,我無法控制更改表格代碼,因爲它位於客戶端網站上。 – glasnt 2010-05-03 05:26:48

+0

你有沒有深入到底?從表面上看,權限問題(即允許寫入但不能讀取的用戶)看起來比自動提交設置更不可能。 – Peter 2011-11-04 21:48:18

回答

2

您是否在目標環境中打開了一些設置,其中每個語句都是自動提交的? (我的經驗是在SQL Server中,默認情況下是這樣,但我在Oracle中理解,默認情況下是保持事務處於打開狀態,直到明確提交。注意,自2000年以來我沒有碰到Oracle)

+0

據我所知,它沒有設置爲自動提交。我們必須編寫代碼來顯式提交事物,到其他表中,如果我們在代碼中引發異常,則撤消它們自己。 – glasnt 2010-04-23 06:49:03

0

我覺得達米安是對的,有一個自動提交。唯一的其他選擇,我可以想出是某種形式的連接池的問題(即選擇正在從一個單獨的會話做插入)

+0

該選擇和插入的會話是相同的。這個問題與DBA一直有關,因爲我發佈了原始問題,而且我不確定進度從它可能涉及讀取/更新用戶權限這一事實。 – glasnt 2010-05-02 23:36:36

2

ON COMMIT DELETE ROWS =數據在一個事務中

ON COMMIT PRESERVE ROWS =數據在一個數據庫會話(具有2個會話的一個用戶= 2個會話=不同的內容)

如果GTT使用ON COMMIT DELETE ROWS定義,那麼在任何顯式提交或隱式提交後(=隱式提交=在包含例如截斷表,修改索引,添加分區,修改列,交換分區):

CREATE GLOBAL TEMPORARY TABLE GTT__TEST (A NUMBER) ON COMMIT DELETE ROWS; 
INSERT INTO GTT__TEST VALUES (1); 
SELECT * FROM GTT__TEST; -- 1 ROW; 
COMMIT; -- commit = delete rows 
SELECT * FROM GTT__TEST; -- 0 ROWS; 
INSERT INTO GTT__TEST VALUES (1); 
SELECT * FROM GTT__TEST; -- 1 ROW; 
ALTER TABLE GTT__TEST MODIFY A NOT NULL; -- DLL = commit = delete rows 
SELECT * FROM GTT__TEST; -- 0 ROWS 

如果GTT與ON COMMIT PRESERVE ROWS定義,將舉行,直到會議結束數據:

DROP TABLE GTT__TEST; 
CREATE GLOBAL TEMPORARY TABLE GTT__TEST (A NUMBER) ON COMMIT PRESERVE ROWS; 
INSERT INTO GTT__TEST VALUES (1); 
SELECT * FROM GTT__TEST; -- 1 ROW 
COMMIT; 
SELECT * FROM GTT__TEST; -- 1 ROW