Reputation: 5
I have a table containing 3 columns eid,salary,newsal.
I have already inserted eid and salary for all the employees. Now,if I update the salary of any employee I want a trigger which directly increments the salary of that employee by 20% and stores it into the column newsal.
I used a trigger :
create or replace trigger pp1
after update on empsal
for each row
BEGIN
:new.newsal := :old.sal*1.2;
END;
I can't execute this trigger as it says
Error report: ORA-04084: cannot change NEW values for this trigger type 04084. 00000 - "cannot change NEW values for this trigger type" *Cause: New trigger variables can only be changed in before row insert or update triggers. *Action: Change the trigger type or remove the variable reference.
My table is defined as:
> create table empsal(empno varchar2(8),sal number,newsal number,primary
> key(empno));
Upvotes: 0
Views: 707
Reputation: 14741
You can create a BEFORE UPDATE
trigger as
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);
UPDATE empsal
SET sal = 130;
+-------+-----+--------+
| EMPNO | SAL | NEWSAL |
+-------+-----+--------+
| 123 | 130 | 156 |
+-------+-----+--------+
If you are using Oracle 11g, leverage the concept of virtual column, so try as
CREATE TABLE empsal
(
empno VARCHAR2 (8),
sal NUMBER,
newsal GENERATED ALWAYS AS (sal * 1.2) VIRTUAL,
PRIMARY KEY (empno)
);
Upvotes: 1
Reputation: 35154
Its because AFTER
-triggers cannot write to the :new
-values. Use a BEFORE
-trigger instead. Confer, for example, this documentation on triggers (emphasis mine):
BEFORE
Specify BEFORE to cause the database to fire the trigger before executing the triggering event. For row triggers, the trigger is fired before each affected row is changed.
Restrictions on BEFORE Triggers BEFORE triggers are subject to the following restrictions:
- You cannot specify a BEFORE trigger on a view or an object view.
- You can write to the :NEW value but not to the :OLD value.
AFTER
Specify AFTER to cause the database to fire the trigger after executing the triggering event. For row triggers, the trigger is fired after each affected row is changed.
Restrictions on AFTER Triggers AFTER triggers are subject to the following restrictions:
- You cannot specify an AFTER trigger on a view or an object view.
- You cannot write either the :OLD or the :NEW value.
Upvotes: 1