2011-07-07 70 views
1

我有一個Oracle觸發器調用PRAGMA AUTONOMOUS_TRANSACTION定義的存儲過程。從觸發器傳遞的值已經被提交,但似乎這些值在存儲過程中不可用?我對此並不積極,因爲調試/日誌/提交的能力很困難,輸出的時間讓我感到困惑。我想知道是否期望任何傳遞值都可以在存儲過程中使用,而不管AUTONOMOUS_TRANSACTION是什麼? 謝謝從觸發器調用Oracle自主存儲過程

回答

5

作爲參數傳遞給存儲過程的值始終可供存儲過程使用。這個過程是否使用自治事務來聲明並不重要。

在自治事務中運行的代碼無法看到調用事務所做的更改。當人們在看到他們期望的數據時出現問題時,10次中有9次是這個問題的根源。

如果您的存儲過程除了向日志表中寫入內容之外的任何操作,我對使用自治事務格外謹慎。如果您將自主事務用於記錄以外的其他任何事情,則幾乎肯定會錯誤地使用它們。而且您可能會引入大量與競爭條件和交易完整性相關的錯誤。

+0

表ABC上的觸發器調用在同一個ABC表上進行選擇的存儲過程。在這種情況下,如果沒有編譯指示,我從存儲過程中收到「ORA-04091:表ABC變異,觸發器/函數可能看不到它」錯誤。存儲過程中除SELECT語句以外的唯一活動是在執行INSERT/COMMIT的異常情況下完成的日誌記錄。 – McArthey

+2

@McArthey - 使用自治事務處理突變觸發器錯誤幾乎總是一個錯誤。由於SELECT語句無法看到觸發語句所做的更改,這意味着您的SELECT應該在before語句觸發器中完成(因爲您不關心當前語句正在進行的更改)或者您需要更強大的解決方案。 –

+0

謝謝。是的,的確,我並不在乎觸發器正在發生的變化,但我們正在關注具體的變化。當發生更改時,會調用存儲過程來對行值進行一些分析。存儲過程不會進行任何更新或插入到有問題的表中。 – McArthey

0

「的觸發邏輯是有條件 它調用 存儲過程以從上表A中 值中選擇,使得表B可以 與計算出的值來更新更新表B」。

也許表B真的應該是從表A派生的物化視圖?我們可以在填充MViews的查詢的WHERE子句中構建很多複雜性。 Find out more.

0

如果你在table_x上有一個行級觸發器,那麼這個觸發器可以被相同的語句多次觸發,因爲不同的行受到該語句的影響。

這些行受到影響的順序是不確定的。因此,在執行行級觸發期間,table_x的狀態是不確定的。這就是爲什麼會引發MUTATING TABLE異常。

通過查看錶的提交狀態(即排除該語句和交易中的其他語句所做的所有更改),自治事務「欺騙」。

如果您希望存儲過程查看table_x的狀態以響應該表上的活動,則需要在所有行更改完成後完成(即在語句級觸發器中,而不是行中級別觸發器)。

設計模式通常是在行級別觸發器中設置一個標誌(包級別變量),在AFTER語句級別觸發器中檢查該標誌,並在必要時對其進行操作並將其重置。

+0

在我的場景中,我相信那麼Table_A觸發器會插入到Table_B中。 Table_B AFTER觸發器會觸發並執行將從Table_A中SELECT並更新Table_B的存儲過程?我不會有與存儲過程相同的問題,因爲它是同一事務的所有部分? – McArthey