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如何创建行级触发器?的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE触发器

创建计算每个新插入员工的总工资的行级触发器

oracle_触发器

oracle 触发器学习

Oracle触发器实例(网搜)

如何在Oracle触发器中使用查询语句