插入触发器oracle

时间:2016-12-29 23:38:23

标签: oracle plsql triggers

嘿,如果总薪水大于1000,我想阻止插入新记录,所以我尝试使用触发器来解决这个问题

    names1 = open('textfile_I_imported', 'r')
    names1_file = names.read()

    names2 = open('diff_texfile_I_imported', 'r')
    names2_file = names2.read()

    spinvalue = tk.StringVar()

    spinbox1=tk.Spinbox(self, textvariable=spinvalue, values=(textfile_I_imported))
    spinbox1.config(width='25')
    spinbox1.place(x=55, y=145)

    spinbox2=tk.Spinbox(self, textvariable=spinvalue, values=(diff_textfile_I_imported))
    spinbox2.config(width='45')
    spinbox2.place(x=225, y=145)

正如你在这里看到的那样,我用光标得到总和,然后获取值,如果条件比较,但它不能正常工作!即使工资超过范围也会插入新记录

任何人都知道如何解决这样的问题。

2 个答案:

答案 0 :(得分: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应该如何处理这种情况,例如,在一个单独的行中插入两行声明?如果插入而没有另一行,则两条行可能与条件匹配,但如果同时插入它们,则超出限制。这将导致尼古拉斯所描述的错误。你会在SO中找到很多答案

答案 1 :(得分:0)

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

请点击这些线条。看起来你没有使用任何异常处理过程来在工资超过1000时向用户显示任何错误消息。还有:new.sal:=:new.sal s不需要的额外行。 new.sal将始终包含最新或更新的值。因此,不需要显式分配值。你可以改变下面给出的代码并试一试。 belw代码工作正常。

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;
/