I have trigger on delete I want to delete policeman but when I delete him all other policeman that he is their boss will have null in their boss field so I used this code
create or replace trigger switch_boss before delete on policeman for each row declare boss number; begin boss := :new.bossid; if(:new.policemanid = :new.bossid)then select policemanid into boss from (select * from policeman order by dbms_random.value) where rownum =1; end if; update policeman set bossid = boss where bossid = :new.policemanid; end switch_boss;
I got error
ORA-04091: table SYSTEM.POLICEMAN is mutating, trigger/function may not see it ORA-06512: at "SYSTEM.SWITCH_BOSS", line 13 ORA-04088: error during execution of trigger 'SYSTEM.SWITCH_BOSS'
any ideas?
UPDATE: I used compund trigger its works but not as I wanted. I wanted to set the boss of the deleted policeman as the boss for the ones he was boss of. the problem is when deleting I cant now which policemans have the deleted policem as boss. I can find them because they have null in the field after the delete but they may belong to other deleted policeman.
this is the trigger I made:
create or replace trigger switch_boss for delete on policeman compound trigger after statement is cursor c is select * from policeman where bossid is null for update; boss number; begin for r in c loop select policemanid into boss from (select * from policeman order by dbms_random.value) where rownum =1; update policeman set bossid = boss where current of c; end loop; end after statement; end switch_boss;
Advertisement
Answer
This is a very common problem when getting started with triggers.
Oracle does not let your row-level trigger access its base table (POLICEMAN
) other than through the :NEW
and :OLD
pseudo-records. The idea is that the table is in a state of flux, so it cannot be queried or modified by the trigger..
A typical way of handling this is to create two triggers: a row-level trigger followed by a statement-level trigger. The row-level trigger registers all of the changes in a package (packages can hold state), while the statement-level trigger follows up and applies all of the necessary modifications based on what happened in the rows–a statement-level trigger can modify the base table.
Here is a description on how to do this: Get rid of mutating table trigger errors with the compound trigger
In that article, Steven Feuerstein describes not only the traditional package-based solution to the problem, but he also provides a more modern compound-trigger-based solution.