oracle如何创建行级触发器?
Posted
技术标签:
【中文标题】oracle如何创建行级触发器?【英文标题】:how to create row level trigger in oracle? 【发布时间】:2013-02-06 06:42:05 【问题描述】:我在hr
架构中有一个名为employee
的表,我需要在此表上创建行级触发器,以便每当我尝试更新员工表上的薪水时,我确保不会减少薪水!
我试过这个,但我得到一个错误:
错误报告:ORA-01748:此处仅允许简单的列名 01748。 00000 - "这里只允许简单的列名
CREATE or REPLACE TRIGGER salary_dec_trigger
BEFORE UPDATE OF emp.salary
ON emp
FOR EACH ROW
BEGIN
if(:new.salary>:old.salary)
then
update emp set emp.salary=emp.salary+:new.salary where emp.employee_id=:new.employee_id;
else
rollback;
end if;
END;
/
【问题讨论】:
你能解释一下“不能得到好的结果”是什么意思吗? 我的意思是我遇到了运行时错误,伙计。错误报告:ORA-01748:此处只允许简单的列名 01748。00000 -“此处只允许简单的列名” *原因:*操作: 只指定列名salary
,而不是限定列名emp.salary
。同样适用于employee_id
是的,我也试过这个,伙计......现在它已经编译了,但是,当我尝试更新薪水时,它给出了错误!is:错误报告:SQL 错误:ORA-04091:表 HR。 EMP 正在变异,触发器/函数可能看不到它 ORA-06512:在“HR.SAL_UPDATE”,第 5 行 ORA-04088:执行触发器 'HR.SAL_UPDATE' 04091 期间出错。00000 - “表 %s.%s 是变异,触发器/函数可能看不到它”
这很棘手。您可以尝试使用after
触发器而不是before
因为在您的情况下它正在尝试读取尚未更新的列值salary
。
【参考方案1】:
CREATE or REPLACE TRIGGER salary_dec_trigger
BEFORE UPDATE OF salary ON emp
FOR EACH ROW
BEGIN
if(:new.salary < :old.salary) then
raise_application_error(-20001, 'Salary can''t be decreased');
end if;
END;
【讨论】:
这是正确的方法,但如果您解释了 OP 发生了什么问题,您的答案会好得多。也就是说,当触发器被触发时,您不应该(在某些情况下不能)更新触发器所基于的表。【参考方案2】:据我所知,从您的代码中可以看出,您正在尝试每次更新员工的薪水时,实际上都会将其与他之前的薪水相加,对吗?并且只允许加薪,绝不减薪。
那你为什么不直接说:new.salary = :old.salary + :new.salary
?并跳过回滚,只需执行:new.salary = :old.salary
;
如果它不起作用,您应该尝试使用自治事务的过程来执行此操作,但这就是前触发器应该允许您直接执行的操作 (check this here)。
【讨论】:
以上是关于oracle如何创建行级触发器?的主要内容,如果未能解决你的问题,请参考以下文章