2009-10-23 41 views
0

有人可以幫助我更正下面的觸發器嗎?我被分配了這個問題,但我的技術技能是有限的。ORA-04091創建或替換觸發xxx在插入更新xxx之前

我的腳本打下面的錯誤(ORA 4091):

處理標準訂單號:27179

................... ...................

更新訂單狀態..

完成審批處理。

DIST ID 611294gl量10000.88 bill_del_amount 0 l_amount 10000.88

一些異常出現** ORA-04091:表PO.PO_DISTRIBUTIONS_ALL被突變,

觸發/功能可能無法看到它**

ORA-06512:在 「APPS.XXAET_PO_DELIVER_TO_TRG」,

線22

ORA-01403:無數據發現

ORA-04088:觸發

「APPS.XXAET_PO_DELIVER

PL/SQL過程已成功完成的執行期間的錯誤。

SQL>

我設法找到在客戶機定製的觸發,但是研究後我無法針點什麼錯與SQL。請幫忙!

CREATE OR REPLACE TRIGGER apps.xxaet_po_deliver_to_trg 
BEFORE INSERT OR UPDATE ON po_distributions_all 
    FOR EACH ROW 
DECLARE 
    l_emp_name VARCHAR2 (300); 
    l_sqlcode VARCHAR (30) := SQLCODE; 
    l_sqlerrm VARCHAR (400) := SUBSTR (SQLERRM, 1, 399); 
    x_profile_value VARCHAR (10) ; 
BEGIN 

x_profile_value := fnd_profile.value('ORG_ID'); 
    Select Ship_To_Location_ID 
    INTO :NEW.Deliver_To_Location_Id 
    from PO_LINE_LOCATIONS_ALL 
    WHERE line_location_id = :NEW.line_location_id 
    AND ORG_ID = x_profile_value 
    ; 

EXCEPTION 
    WHEN OTHERS 
    THEN 
     NULL; 

    UPDATE PO_DISTRIBUTIONS_ALL SET Deliver_To_Location_Id = :NEW.Deliver_To_Location_Id 
    WHERE line_location_id = :NEW.line_location_id; 

END; 

/

非常感謝! Kenneth, 。

+0

您的意思是隻有在SELECT語句失敗時才執行UPDATE語句? – APC 2009-10-23 04:58:27

回答

2

ORA-04091的根本原因是EXCEPTION處理 - 您無法對觸發器附加的表執行任何操作。在這種情況下 - PO_DISTRIBUTIONS_ALL

參考:ORA-04091 Error

我建議你封裝邏輯在存儲過程中,並把它在之前的INSERT/UPDATE語句的INSERT/UPDATE存儲過程。

+0

同意,請參閱http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html#和http://asktom.oracle.com/pls/asktom/f?p=100:11 :0 :::: P11_QUESTION_ID:2047433200346833001 – 2009-10-23 07:35:49

5

變異表錯誤意味着觸發器代碼可能不會在其擁有的表上發出DML語句。這是爲了避免遞歸行爲。解決方案非常簡單。刪除UPDATE語句。

本聲明背後的意圖不是很清楚。這是非常常見的,因爲ORA-4091錯誤通常表示設計不良,例如數據模型不夠規範。我認爲這是你的情況。因此,解決這個問題需要比我們更多的商業知識。

它也似乎是你的SELECT語句失敗(發佈的錯誤堆棧有點困惑)。你試圖用臭名昭着的WHEN OTHERS THEN NULL;結構來壓制這個陳述的失敗。這是Teh Suck!立即將其刪除。你需要需要才能知道你的代碼失敗了,爲什麼。如果以下人羣:NEW.Deliver_To_Location_Id是可選的,那麼您不介意查找「失敗」,將OTHERS替換爲NO_DATA_FOUND

3

此問題的根本原因是使用觸發器來執行除日誌記錄或其他非應用程序相關任務以外的任何操作。以這種方式使用它們進行數據操作是非常糟糕的做法。

此外,還使用EXCEPTIONS子句以靜默方式捕獲錯誤並調用該更新。而當他們使用NULL時,悲劇正在等待發生。

所有可怕的PL/SQL編程實踐絕不應該通過代碼審查。

重構時間。

1

正如前面的答案中所提到的,您正在更改錯誤,因爲您正在更新不允許的觸發器內的同一個表。

由於您正在使用「更新和插入之前」觸發器,所以您只需設置:new.deliver_to_location_id並使用正確的值。既然你已經在select語句中這樣做了,爲了修正你的觸發器,只需刪除update語句,因爲你的select語句已經更新記錄字段。

作爲增強功能,您可以用「when no_data_found」替換「when others」異常,這將幫助您拋出所有其他意外錯誤。

相關問題