触发检查新员工不存在

时间:2014-03-07 16:23:39

标签: oracle plsql triggers oracle-apex

我正在尝试创建一个触发器,以检查我的emp_mb表中是否已存在员工,并收到此错误消息

ORA-00969:缺少ON关键字

任何想法?

CREATE OR REPLACE TRIGGER adduser_mb
BEFORE 
INSERT OR UPDATE emp_id 
ON emp_mb
FOR EACH ROW 
DECLARE 
DUMMY INTEGER;
BEGIN 
     SELECT COUNT(*) INTO DUMMY 
     FROM emp_mb 
     WHERE emp_id = :new.emp_id

     IF (dummy > 0) 
        THEN raise_application_error(-20501 
        'Employee ID' || :new.emp_id || ' already exists');
END IF;
END;

2 个答案:

答案 0 :(得分:8)

您无法在单个(非复合)触发器中实际执行此操作。

emp_mb上的行级触发器通常无法查询emp_mb。解决语法问题后,您将获得变异表异常。

确保emp_id唯一的正确方法是在表格上创建唯一约束。

alter table emp_mb
  add( constraint uk_emp_id unique (emp_id) );

如果你真的,真的,真的想用触发器来做这件事,你需要多个触发器(或者如果你使用11.2则实现多个触发器的复合触发器)。您需要一个声明了emp_id值集合的包。您需要一个初始化该集合的before语句触发器。您需要一个行级触发器,将:new.emp_id值插入该包的集合中。然后你需要一个after语句触发器来遍历集合并进行检查。这是你必须实现,调试和维护的很多动作。

但实际上它不仅仅是代码的泛滥 - 你还需要实现自己的序列化机制。否则,假设您允许系统中有多个用户,则两个会话都可以插入具有相同emp_id的行,每个会话的检查成功,然后让两个会话都提交给您留下重复的值你的桌子。这意味着您还需要实现一些逻辑,以确保在任何时间点只有一个会话可以将数据插入此表。反过来,这将极大地降低系统的可扩展性,并且很可能导致会话保持锁定的维护问题,阻止系统中的其他所有人,直到DBA找到并杀死它们为止。

答案 1 :(得分:3)

我认为你错过了OF

BEFORE 
INSERT OR UPDATE OF emp_id 
ON emp_mb

顺便说一下,你可以使用UNIQUE约束,不是吗?