【问题标题】:how to create row level trigger in oracle?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

标签: oracle plsql triggers oracle11g


【解决方案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)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-03
    • 2011-01-06
    • 2014-10-28
    • 2016-05-31
    • 2019-05-03
    • 2013-12-24
    • 2018-02-07
    • 2011-06-21
    相关资源
    最近更新 更多