2016-12-29 82 views
-2

嘿,我想阻止插入新記錄,如果工資總額大於1000,所以我試圖用觸發插入扳機甲骨文

CREATE OR REPLACE TRIGGER totalsal 
    BEFORE INSERT OR UPDATE 
    ON saltable 
    FOR EACH ROW 
DECLARE 
    CURSOR sumsalary IS 
     SELECT SUM(sal) AS sum_salary FROM saltable; 

    total         NUMBER; 
BEGIN 
    OPEN sumsalary; 

    FETCH sumsalary INTO total; 

    DBMS_OUTPUT.PUT_LINE('value is '); 
    DBMS_OUTPUT.PUT_LINE(total); 

    CLOSE sumsalary; 

    IF (total < 1000) 
    THEN 
     DBMS_OUTPUT.PUT_LINE('in range'); 
     :new.sal := :new.sal; 
    ELSE 
     DBMS_OUTPUT.PUT_LINE('exceed limit'); 
    END IF; 
END; 
/

來解決這個問題,你可以在這裏看到我用遊標得到總和然後獲取價值,如果比較的條件,但它不完美的工作!即使總額超出範圍,它也會插入新紀錄

任何人都知道如何解決這樣的問題。

+3

我注意到你發佈了13個問題,從未接受過答案。你從來沒有得到一個好的答案,或者還有另一個原因,你爲什麼永遠不會接受答案? – Aleksej

回答

0
IF (total < 1000) 
    THEN 
     DBMS_OUTPUT.PUT_LINE('in range'); 
     :new.sal := :new.sal; 
    ELSE 
     DBMS_OUTPUT.PUT_LINE('exceed limit'); 
    END IF; 

請chnage這些線路老兄這麼多的答案。看起來你沒有使用任何異常處理過程在薪水超過1000時向用戶顯示任何錯誤消息。還有:new.sal:=:new.sal s不需要的額外行。 new.sal將始終包含最新或更新的值。因此不需要明確分配值。 U可以更改下面給出的代碼並嘗試一下。貝爾代碼工作正常。

CREATE OR REPLACE TRIGGER totalsal 
    before INSERT OR UPDATE 
    ON saltable 
    FOR each row 
DECLARE 
    CURSOR sumsalary IS 
     SELECT SUM(sal) AS sum_salary FROM saltable; 

    total         NUMBER; 
BEGIN 
    OPEN sumsalary; 

    FETCH sumsalary INTO total; 
    total:=total+:new.sal; 
    DBMS_OUTPUT.PUT_LINE('value is'||total); 

    CLOSE sumsalary; 

    IF (total < 1000) 
    THEN 
     DBMS_OUTPUT.PUT_LINE('in range'); 
     Your insert statement; 
     ELSE 
     raise_application_error(-20022, 'Salary is beynd the limit'); 
    END IF; 
END; 
/
+0

Bhasker謝謝你的讚賞,這是我想要的。 – Mariam

+0

任何時候兄弟高興,我的輸入,幫助ü:) –

+0

這會給正是尼古拉斯·克拉斯諾夫注意到 – Aleksej

2

您的觸發器不會阻止插入,而只是打印一條消息。 如果你想避免在某些情況下插入,你應該提出一個錯誤;例如:

... 
     DBMS_OUTPUT.PUT_LINE('exceed limit'); 
     raise_application_error(-20001, 'Sal exceeds limit'); 
... 

另外注意,如果表是空的,SUM會給NULL,這可能使你的檢查失敗。

你甚至可以避開遊標;如果你需要計算SUM,並把結果在一個變量,你可以簡單地這樣做:

select sum(...) 
into yourVariable 
from ... 

而且:new.sal:=:new.sal;什麼都不做,可能被刪除。

並注意到尼古拉斯克拉斯諾夫的重要評論;試圖澄清它,如果您構建行級觸發器(FOR EACH ROW)並且此觸發器必須檢查表中其他行的值,那麼Oracle如何處理這種情況,例如,在單個語句中插入兩行的情況?有可能兩行如果插入時沒有另一行匹配條件,但如果兩者都插入,則超出限制。這將導致尼古拉斯所描述的錯誤。你會發現這個

+3

應該指出,可能會引發'table is mutating'錯誤。爲什麼我說可能而不會。 'insert'觸發器在你使用簡單的'insert into values()'語句時不會產生'table is mutating'異常,但是如果你使用'insert into select from'(即使'select'語句返回只有1行)。因此,要麼定義一個視圖並使用'而不是'觸發器或複合觸發器,或者定義一組API(存儲過程添加新記錄)並在那裏執行薪水檢查。 –

+0

@NicholasKrasnov我沒有注意到主要問題。謝謝 – Aleksej