如何避免PL / SQL

时间:2017-06-15 10:48:52

标签: sql oracle oracle-sqldeveloper

我有一个包含3列eid,salary,newsal的表。

我已经为所有员工插入了eid和薪水。 现在,如果我更新任何员工的工资,我想要一个触发器,直接将该员工的工资增加20%并将其存储到新闻栏中。

我使用了触发器:

create or replace trigger pp1
after update on empsal
for each row
BEGIN
:new.newsal := :old.sal*1.2;
END;

我无法执行此触发器,因为它说

  

错误报告:ORA-04084:无法更改此触发器的新值   类型   04084. 00000 - “无法更改此触发类型的新值”   *原因:新的触发变量只能在行之前更改              插入或更新触发器。   *操作:更改触发器类型或删除变量引用。

我的表定义为:

> create table empsal(empno varchar2(8),sal number,newsal number,primary
> key(empno));

2 个答案:

答案 0 :(得分:1)

您可以创建BEFORE UPDATE触发器

CREATE OR REPLACE TRIGGER test_trg
   BEFORE UPDATE
   ON empsal
   FOR EACH ROW
BEGIN
   :NEW.newsal := :new.sal * 1.2;
END;

E.g。

INSERT INTO empsal (empno, sal)
     VALUES (123, 120);

enter image description here

UPDATE empsal
   SET sal = 130;


+-------+-----+--------+
| EMPNO | SAL | NEWSAL |
+-------+-----+--------+
|   123 | 130 |    156 |
+-------+-----+--------+

如果您使用的是Oracle 11g,请利用虚拟列的概念,因此请尝试

CREATE TABLE empsal
(
   empno    VARCHAR2 (8),
   sal      NUMBER,
   newsal   GENERATED ALWAYS AS (sal * 1.2) VIRTUAL,
   PRIMARY KEY (empno)
);

答案 1 :(得分:1)

因为AFTER - 触发器无法写入:new - 值。请改用BEFORE - 触发器。例如,授予this documentation on triggers(强调我的):

  

<强> BEFORE

     

指定BEFORE以使数据库在之前触发触发器   执行触发事件。对于行触发器,触发器被触发   在每个受影响的行被更改之前。

     

BEFORE触发器的限制BEFORE触发器受制于   以下限制:

     
      
  • 您无法在视图或对象视图上指定BEFORE触发器。
  •   
  • 您可以写入:新值,但不能写入:OLD值。
  •   
     

<强> AFTER

     

指定AFTER以使数据库在之后触发触发器   执行触发事件。对于行触发器,触发器被触发   在每个受影响的行被更改之后。

     

AFTER触发器的限制AFTER触发器受制于   以下限制:

     
      
  • 您无法在视图或对象视图上指定AFTER触发器。
  •   
  • 您无法写入:OLD或:NEW值。
  •