2012-07-31 40 views
2

我有一個觸發器,用於表格中的幾個字段。但由於某種原因,如果另一個字段發生了變化(這在觸發器中沒有定義),它仍然會觸發。一個表格字段的觸發器適用於所有表格字段

CREATE OR REPLACE TRIGGER INTEGRATION_EMPLOYMENT 
    AFTER UPDATE OF start_day_of_employment, end_of_employment ON hr_employment_data 
    FOR EACH ROW 
    DECLARE 
    BEGIN 
     IF UPDATING THEN 
      MERGE INTO ad_integration intg USING dual ON (intg.user_id = :NEW.user_id AND intg.integrated = 'NO') 
      WHEN MATCHED THEN 
       UPDATE SET 
         intg.start_day_of_employment = decode(:NEW.start_day_of_employment, NULL, ' ', :NEW.start_day_of_employment), 
         intg.end_of_employment = decode(:NEW.end_of_employment, NULL, ' ', :NEW.end_of_employment), 
         intg.manager_status = :NEW.manager_status, 
         intg.pid = (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id), 
         intg.network_access_start_date = (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id) 
      WHEN NOT MATCHED THEN 
       INSERT (intg.user_id, intg.start_day_of_employment, intg.end_of_employment, intg.manager_status, intg.pid, intg.network_access_start_date 
       VALUES (:NEW.user_id, :NEW.start_day_of_employment, :NEW.end_of_employment, :NEW.manager_status, (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id), (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id)); 
END IF; 

END HR_ADINTEGRATION_EMPLOYMENT; 

是因爲使用DUAL還是我缺少的東西?

乾杯! :-)

+0

可能是你有另一個觸發器沒有指定列。 – 2012-07-31 06:26:05

+2

如何更新HR_EMPLOYMENT_DATA?如果您通過某種用戶界面進行更新,則即使只有部分列的值發生更改,用戶界面也可能會更新所有列。另外,您是否有充分的理由不使用視圖按需查找HR_EMPLOYMENT_DATA中的值(而不是使用觸發器嘗試使AD_INTEGRATION保持最新狀態)?使用觸發器很難做到這一點。你有在HR_EMPLOYMENT_DATA上插入和刪除觸發器嗎?在AD_INTEGRATION上更新和插入觸發器怎麼辦? – 2012-07-31 11:24:16

+0

是的,有觸發器是罪魁禍首,所以我想使用視圖是最好的選擇。 (爲什麼我之前沒有想到這個?) – Jaanna 2012-08-01 05:28:52

回答

2

如果你想離開的結構是,只有處理時觸發的specifc領域發生變化,那麼就做一個快速的比較(新代碼行7和8):

CREATE OR REPLACE TRIGGER INTEGRATION_EMPLOYMENT 
AFTER UPDATE OF start_day_of_employment, end_of_employment ON hr_employment_data 
FOR EACH ROW 
DECLARE 
BEGIN 
    IF UPDATING 
     AND (:NEW.start_day_of_employment <> :OLD.start_day_of_employment 
     OR :NEW.end_of_employment <> :OLD.end_of_employment) THEN 
     MERGE INTO ad_integration intg USING dual ON (intg.user_id = :NEW.user_id AND intg.integrated = 'NO') 
     WHEN MATCHED THEN 
      UPDATE SET 
        intg.start_day_of_employment = decode(:NEW.start_day_of_employment, NULL, ' ', :NEW.start_day_of_employment), 
        intg.end_of_employment = decode(:NEW.end_of_employment, NULL, ' ', :NEW.end_of_employment), 
        intg.manager_status = :NEW.manager_status, 
        intg.pid = (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id), 
        intg.network_access_start_date = (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id) 
     WHEN NOT MATCHED THEN 
      INSERT (intg.user_id, intg.start_day_of_employment, intg.end_of_employment, intg.manager_status, intg.pid, intg.network_access_start_date 
      VALUES (:NEW.user_id, :NEW.start_day_of_employment, :NEW.end_of_employment, :NEW.manager_status, (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id), (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id)); 
END IF; 

END HR_ADINTEGRATION_EMPLOYMENT; 
相關問題