2017-10-08 97 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 

这不会解决您的“总小时数”问题,但它会处理您报告的错误。

祝你好运。