我正在尝试创建一个触发器,以检查我的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;
答案 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约束,不是吗?