2013-04-18 39 views
1

我有兩個表,PRODUCTS和STATE_PRICE。每種產品的價格因州而異。 PRODUCTS表追蹤所有州的每種產品的平均成本。我試圖編寫一個觸發器,在STATE_PRICE表中插入,更新或刪除價格時,將更新PRODUCTS表中項目的平均價格。我編寫了以下編譯的觸發器,但是當我測試它時,我收到了一條突變的錯誤消息。我理解變異錯誤的概念,我試圖更新一個觸發器正在執行的表,但我實際上是在STATE_PRICE表上執行觸發器時嘗試更新PRODUCTS表。觸發器上的突變錯誤以計算平均成本

create or replace trigger trg_avg_cost 
after insert or update or delete on state_price 
for each row 

declare 
w_price state_price.list_price%type; 
w_product state_price.productid%type; 

begin 
w_price := :new.list_price; 
w_product := :new.productid; 

update products 
set avg_cost_per_unit = (select avg(w_price) from state_price 
where productid = w_product); 

end; 
/

特定錯誤消息我得到說:

錯誤報告:

SQL Error: ORA-04091: table STATE_PRICE is mutating, trigger/function may not see it 
ORA-06512: at "TRG_AVG_COST", line 9 
ORA-04088: error during execution of trigger 'TRG_AVG_COST' 
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it" 
*Cause: A trigger (or a user defined plsql function that is referenced in 
      this statement) attempted to look at (or modify) a table that was 
      in the middle of being modified by the statement which fired it. 
*Action: Rewrite the trigger (or function) so it does not read that table. 
+0

我認爲您必須在聲明中使用Pragma Autonomous_transaction並再次檢查 – ajmalmhd04

回答

1

可能存在refrential完整性約束(在產品ID),也可提出同樣的錯誤。如果是這樣的話,下面的鏈接可以幫助你避免錯誤。

http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936

+0

如果觸發器中的SQL語句嘗試訪問觸發器所在的表,則ORA-04091將僅從行觸發器中拋出。外鍵違例會導致不同的錯誤(根據具體情況,ORA-02291,ORA-02292或ORA-02298)。 –

0

在同一行不觸發SQL語句可以訪問該觸發器中的表格。您的SELECT AVG(W_PRICE) FROM STATE_PRICE WHERE PRODUCTID = W_PRODUCT是導致錯誤的原因。解決此限制的經典方法是使用複合觸發器 - 文檔here。有關實現複合觸發器的示例,另請參閱我對this StackOverflow question的回答。

分享和享受。

+0

謝謝你的幫助。它看起來像一個複合觸發器就是我需要的東西! –