2017-10-08 84 views
0

我是Oracle的初學者。我想創建一個INSTEAD OF觸發器執行,沒有導師應在一個月創建而不是插入觸發器

這項工作超過60個小時的規則是我到目前爲止

CREATE TRIGGER limit_hour 
    INSTEAD OF INSERT ON SESSIONHOURS 
    DECLARE 
    totalHours NUMBER := 60; 
    monthOnly DATE; 
    totalSession NUMBER; 
    FOR EACH ROW 
    BEGIN 
     INSERT INTO SESSIONHOURS(SESSIONDATEKEY, TUTORKEY, TOTALSESSION) 
     SELECT EXTRACT (MONTH FROM DATE S.SESSIONDATEKEY), S.TOTALSESSION 
     INTO monthOnly, totalSession 
    FROM SESSIONHOURS S 
    END; 

錯誤「不適當INTO」不斷彈出。此外,我需要爲每個會話分配每個會話的總和(每個30分鐘),然後將其與「totalHour」進行比較。我如何將時間值分配給日期值?任何建議,將不勝感激

+0

這個觸發器*假設*做什麼? – Mureinik

+0

執行規則:沒有導師應該在一個月內工作超過60小時 –

+0

是否有一個原因,你有INSERT INTO,然後SELECT INTO在同一個語句中?我假設你想要一個SELECT INTO變量,執行一個檢查(<= 60),然後插入該值或返回一個錯誤? – bbrumm

回答

0

與其使用INSTEAD OF觸發器,在我看來,BEFORE INSERT觸發器更合適。 INSTEAD OF觸發器通常用於將不可插入視圖上的INSERT映射到INSERT中到所需表中。甲BEFORE INSERT觸發器,在另一方面,是每一行被插入表之前燒製,使行中的值進行一致性檢查等可以使用這樣的觸發如下:

CREATE TRIGGER SESSIONHOURS_BI 
    BEFORE INSERT INTO SESSIONHOURS 
    FOR EACH ROW 
DECLARE 
    nTotal_tutor_hours NUMBER; 
BEGIN 
    SELECT SUM(HOURS) 
    INTO nTotal_tutor_hours 
    FROM SESSIONHOURS s 
    WHERE s.TUTORKEY = :new.TUTORKEY; 

    IF nTotal_tutor_hours + :new.HOURS > 60 THEN 
    RAISE_APPLICATION_ERROR(-20001, 'Addition of ' || :new.HOURS || 
            ' for tutor ' || :new.TUTORKEY || 
            ' exceeds monthly limit of 60'); 
    END IF; 
END SESSIONHOURS_BI; 

在觸發處理SESSIONHOURS之前觸發此觸發器。它查詢數據庫以確定其密鑰在INSERT語句(:new.TUTORKEY)中的導師的總工作小時數。如果總工作時間加上新記錄的小時數超過60,則會引發異常,導致INSERT中止。否則,觸發器正常返回並且INSERT繼續。

然而 - 即使這樣也行不通。問題在於觸發器在表SESSIONHOURS上定義,觸發器內部在SESSIONHOURS表上有一個SELECT。這會導致數據庫拋出可怕的ORA-04091異常,並帶有說明文字table SESSIONHOURS is mutating, trigger/function may not see it。有幾種方法可以解決這個問題,其中最好的做法是遵循一個簡單的規則:

***從不*在商業邏輯中實施觸發器!

規則如「導師可能不會工作超過60小時」是一項業務規則。這應該在您的應用程序邏輯中實現,而不是觸發器中。在數據庫中創建一個過程或函數來執行INSERT INTO SESSIONHOURS和任何需要的驗證邏輯,並在每次需要將數據插入SESSIONHOURS時調用該過程。不要試圖將驗證邏輯放入觸發器中 - 您會發現它非常困難,並且會導致永無止境的調試會話,as noted here

祝你好運。

+0

感謝您的規則和您的幫助。說實話,我是學生,這是我的功課,要求是使用INSTEAD OF觸發器。但是,您的回答讓我更好地瞭解觸發器如何在oracle中工作。再次感謝 –

0

您的INSERT語句寫入不當。它應該是:

INSERT INTO SESSIONHOURS(SESSIONDATEKEY, TOTALSESSION) 
    SELECT EXTRACT (MONTH FROM DATE S.SESSIONDATEKEY), S.TOTALSESSION 
    FROM SESSIONHOURS S 

這不會解決您的「總小時數」問題,但它會處理您報告的錯誤。

祝你好運。