Mutating table trigger errors with the compound trigger
A mutating table error (ORA-04091) occurs when a row-level trigger tries
to examine or change a table that is already undergoing change (via an INSERT,
UPDATE, or DELETE statement).
CREATE OR REPLACE TRIGGER equitable_salary_trg
AFTER INSERT OR UPDATE
ON employees
FOR EACH ROW
DECLARE
l_max_allowed employees.salary%TYPE;
BEGIN
SELECT MIN (salary) * 25
INTO l_max_allowed
FROM employees;
IF l_max_allowed < :NEW.salary
THEN
UPDATE employees
SET salary = l_max_allowed
WHERE employee_id = :NEW.employee_id;
END IF;
END equitable_salary_trg;
BEGIN
UPDATE
employees
SET
salary = 100000
WHERE
last_name = 'King';
END;
and I
see this error:
ORA-04091: table EMPLOYEES is mutating,
trigger/function may not see it
ORA-06512: at "EQUITABLE_SALARY_TRG",
line 4
The solution:
1. Define an AFTER STATEMENT trigger that goes through the to-do list, and executes the desired logic for each row.
2. The Compound DML Trigger
CREATE OR REPLACE TRIGGER equitable_salary_trg
FOR UPDATE OR INSERT ON employees
COMPOUND TRIGGER
TYPE id_salary_rt IS RECORD (
employee_id employees.employee_id%TYPE
, salary employees.salary%TYPE
);
TYPE row_level_info_t IS TABLE OF id_salary_rt INDEX BY PLS_INTEGER;
g_row_level_info row_level_info_t;
AFTER EACH ROW IS
BEGIN
g_row_level_info (g_row_level_info.COUNT + 1).employee_id :=
:NEW.employee_id;
g_row_level_info (g_row_level_info.COUNT).salary := :NEW.salary;
END AFTER EACH ROW;
AFTER STATEMENT IS
l_max_allowed employees.salary%TYPE;
BEGIN
SELECT MIN (salary) * 25
INTO l_max_allowed
FROM employees;
FOR indx IN 1 .. g_row_level_info.COUNT
LOOP
IF l_max_allowed < g_row_level_info (indx).salary
THEN
UPDATE employees
SET salary = l_max_allowed
WHERE employee_id = g_row_level_info (indx).employee_id;
END IF;
END LOOP;
END AFTER STATEMENT;
END equitable_salary_trg;
In
this trigger:
- First, declare an array of Employee
record that includes employee id and salary.
- Second, collect affected rows
into the array in the row-level trigger.
- Third, update each affected row
in the statement-level
trigger.
No comments:
Post a Comment