Buf*_*alo 1 sql oracle triggers
我想阻止数据库将任何大于20的值存储到表中.
CREATE OR REPLACE TRIGGER Dont_Allow
AFTER INSERT ON Cities
FOR EACH ROW
WHEN (new.IDCity > 20)
BEGIN
dbms_output.put_line(' Failed to insert ' || :new.IDCity);
delete from orase where IDCity=:new.IDCity;
END;
Run Code Online (Sandbox Code Playgroud)
虽然这确实在没有实际添加任何内容方面有效ID > 20,但每次触发器试图发挥其魔力时,都会显示:
ORA-04091:表SYSTEM.ORASE正在变异,触发器/函数可能看不到它
ORA-06512:在"SYSTEM.DONT_ALLOW",第6行
ORA-04088:执行触发器'SYSTEM.DONT_ALLOW'时出错
做我想做的事的正确方法是什么?
我决定使用触发器:
插入新行后Employees,触发器会检查新员工的工资,如果超过21个单位/小时,管理员的奖金需要5%.Lame,但是嘿 - 我正在使用触发器来解决我没有的问题:结果不会很好.
CREATE OR REPLACE TRIGGER Bite_Bonus
AFTER INSERT ON Employees
FOR EACH ROW
WHEN (new.HourSalary > 20)
BEGIN
update Management set Bonus = Bonus - 5/100 * Bonus;
END;
Run Code Online (Sandbox Code Playgroud)
你不应该使用a TRIGGER,你应该使用a CHECK,比如CONSTRAINT city_id_below_20 CHECK (IDCity < 20).您可以使用ALTER TABLE ADD CONSTRAINT它将它放在现有表上.
正如TC1所指出的,强制执行此类要求的正确方法是使用约束.
如果您被迫使用劣等方法,因为这是一项学校作业,您很可能希望在触发器中引发异常
CREATE OR REPLACE TRIGGER Dont_Allow
BEFORE INSERT OR UPDATE ON Cities
FOR EACH ROW
WHEN (new.IDCity > 20)
BEGIN
RAISE_APPLICATION_ERROR( -20001, 'IDCity cannot exceed 20 so rejecting invalid value: ' || :new.IDCity );
END;
Run Code Online (Sandbox Code Playgroud)