Mutating Trigger

Hello Experts,

I have a prod_ins1 table with st_type,st_sn,wheel. st_type,st_sn are loaded from another table.
Based upon st_type wheel has to be populated. After wheel is populated it has to be loaded into 'wheel' column on Main_prod table.

CREATE OR REPLACE TRIGGER prod_ins1
   after INSERT
   ON prod_test1
 FOR EACH row

DECLARE
vno NUMBER;
BEGIN
update prod_test1 set wheel =
case when st_type = 'Symm ' then 'Wheel 1'
when st_type = 'Clar ' then 'Wheel 2'
when st_type like '%RAM%' then 'RAM'
end;
SELECT count(*) into vno from Main_Prod e  where e.st_sn = :new.st_sn;
if  vno > 0 then
update Main_prod  set
wheel =:new.wheel
where st_sn = :new.st_sn;
else
insert into Main_Prod(wheel)
values
(:new.wheel);
end if;
end;
=======================

ERROR at line 1:
ORA-04091: table MSUSER.PROD_TEST1 is mutating, trigger/function may not

ORA-04088: error during execution of trigger 'MSUSER.PROD_TEST1'

Can you please advise me??

Cheers
spsunAsked:
Who is Participating?
 
Naveen KumarConnect With a Mentor Production Manager / Application Support ManagerCommented:
You cannot update/insert/delete/select to the same table inside the trigger code on which the trigger is firing.

Try the below :

CREATE OR REPLACE TRIGGER prod_ins1
   before INSERT  -- changed after to before
   ON prod_test1
 FOR EACH row
DECLARE
vno NUMBER;
BEGIN
:new.wheel := case when :new.st_type = 'Symm ' then 'Wheel 1'
                   when :new.st_type = 'Clar ' then 'Wheel 2'
                   when :new.st_type like '%RAM%' then 'RAM'
              end;

SELECT count(*) into vno from Main_Prod e  where e.st_sn = :new.st_sn;
if  vno > 0 then
update Main_prod  set
wheel =:new.wheel
where st_sn = :new.st_sn;
else
insert into Main_Prod(wheel)
values
(:new.wheel);
end if;
end;
/

Thanks
0
 
sdstuberCommented:
(if you don't really care how many things there are don't count them all,  count(*) is too expensive an operation if you don't really need it.  Unless, of course, you're counting a unique key.


However, since you're using 10g  (according to your Zones anyway) you can/should use the MERGE statement instead of count update/insert
0
 
sdstuberConnect With a Mentor Commented:
The merge version might look something like this...

When you have variables to merge instead of a query, just select null from dual as a dummy query.
Syntax requires a query so you have to put something there



CREATE OR REPLACE TRIGGER prod_ins1
    BEFORE INSERT
    ON prod_test1
    FOR EACH ROW
DECLARE
    vno   NUMBER;
BEGIN
    :NEW.wheel    :=
        CASE
            WHEN :NEW.st_type = 'Symm '
                THEN 'Wheel 1'
            WHEN :NEW.st_type = 'Clar '
                THEN 'Wheel 2'
            WHEN :NEW.st_type LIKE '%RAM%'
                THEN 'RAM'
        END;
    MERGE INTO main_prod mp
        USING (SELECT NULL
                 FROM DUAL) n
        ON (mp.st_sn = :NEW.st_sn)
        WHEN MATCHED THEN
            UPDATE
               SET mp.wheel = :NEW.wheel
        WHEN NOT MATCHED THEN
            INSERT(wheel)
            VALUES(:NEW.wheel);
END;
/
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
soraCommented:
one of the ways to resolve mutating trigger problem is to have a combination of row level and statement level triggers. so at a BEFORE row level trigger populate a package variable(s) with the values you want to populate. Then in the AFTER statement level trigger read the package variable and populate the column to the table
0
 
sdstuberCommented:
sora, you are correct,
 but in this case using before and after triggers is not necessary because there is no need to go back re-update the same rows.  It's just a matter of using the :new  identifier to allow the trigger to modify the current record
0
 
soraCommented:
yes, correct, sdstuber. if the :new identifier can be used to modify the current record, and if thats ALL thats required, then we do not need a combo of row+statement level triggers
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.