Oracle SQL触发器

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)

TC1*_*TC1 9

你不应该使用a TRIGGER,你应该使用a CHECK,比如CONSTRAINT city_id_below_20 CHECK (IDCity < 20).您可以使用ALTER TABLE ADD CONSTRAINT它将它放在现有表上.


Jus*_*ave 5

正如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)