Solved

ORA-04091: table ... is mutating, trigger/function may not see it

Posted on 2008-06-24
7
7,037 Views
Last Modified: 2013-12-19
I'm trying to fire this trigger but I get ORA-04091: table ... is mutating, trigger/function may not see it
since I'm querying the same table the trigger is firing on.
I tried declaring pragma autonomous_transaction; but that wouldn't update the status on OF. it did however fix the mutation error.
The OL table can contain many records with a status of 1 or 2.
This trigger should fire whenever these statuses are changed and check if all are =2. If so then udpate the status of OF.
How else can I count(*) OL without querying it so as to avoid mutation error & not use a pragma declaration?



CREATE OR REPLACE TRIGGER OL_SPLIT
AFTER UPDATE OF TOORDERID,STATUS ON OL FOR EACH ROW

DECLARE
v_count            number(20);

BEGIN  
  IF (:old.status = 1 and :new.status = 2)  then
        
            select count(*)
            into v_count
            from OL b
            where b.orderid = :new.orderid and b.status = 1;
            
            IF v_count = 0 THEN                   
                  UPDATE OF
                  SET FORMSTATUS = 4
                  WHERE ORDERID  = :new.orderid;
                  commit;                        
            END IF;            
 END IF;            
END;
/
0
Comment
Question by:badtz7229
  • 3
  • 2
  • 2
7 Comments
 
LVL 2

Expert Comment

by:Dom_Cotton
ID: 21865543
Hi,

Just a guess (I havent done this before) but rather than use an update statement on the same table cant you just assign the new value to :new.formstatus on a before update trigger?

Dom
0
 

Author Comment

by:badtz7229
ID: 21871024
if you notice - i'm doing an update on a DIFFERENT table than when the trigger is being fired.
0
 
LVL 2

Expert Comment

by:Dom_Cotton
ID: 21872451
Hi,

I hadnt spotted that (must be the fabulous naming convention of the tables!), however if you use a before update would it not have changed the table already?  Its the select count(*) into... that is unable to execute... i just have a feeling that if you use the before script then you may be able to run the selection.  Alternatively try a commit before the select?  Not sure what that would do...

HTH.
Dom
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

Author Comment

by:badtz7229
ID: 21874487
Apparently, oracle does not allow commits within a trigger.
And I tried using a 'before' and i  still get mutation error
0
 
LVL 73

Accepted Solution

by:
sdstuber earned 500 total points
ID: 21920899
correct, you cannot use commit inside a trigger.
also, anytime you think to use autonomous_transactions and you're not writting an logging function, rethink your approach.  :)


This is a fairly classic problem with a solid solution, it does take some code though.

you'll need to do this in two triggers and a pl/sql package.

first, a before or after row trigger.  you are using after, that's fine.

instead of querying the table and trying the update inside the trigger. instead insert a record into a collection within your package.  In your case the record will consist of nothing but the orderid.

then in an after statement trigger, you will iterate through your collection and do the counts and updates as you have above.

Instead of a collection, you could use a global temporary table.

then you could update all of your records at once with something like this...


UPDATE of
   SET formstatus = 4
 WHERE EXISTS(
           SELECT COUNT(*)
             FROM your_temp_table t, ol
            WHERE ol.orderid = t.orderid
              AND ol.status = 1
              AND of.orderid = t.orderid
           HAVING COUNT(*) = 0)



0
 

Author Comment

by:badtz7229
ID: 21930585
sdstuber:
you stated to use two triggers and a pl/sql package
but is there an simpler approach that can be used just within this one trigger. ?

i mean, all i want to do is a select statement to the table my trigger is firing.
creating 2 extra triggers & a package seems like overhead.


0
 
LVL 73

Expert Comment

by:sdstuber
ID: 21930681
No you have to use two triggers.  One at the row level and one at the statemenrt level.  If you use a temp table instead of a collection you can avoid using a package but you will need some place to store your data external to the triggers.  

If you were on 11g you could have one trigger but essentially the same steps.
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article started out as an Experts-Exchange question, which then grew into a quick tip to go along with an IOUG presentation for the Collaborate confernce and then later grew again into a full blown article with expanded functionality and legacy…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Video by: Steve
Using examples as well as descriptions, step through each of the common simple join types, explaining differences in syntax, differences in expected outputs and showing how the queries run along with the actual outputs based upon a simple set of dem…
This videos aims to give the viewer a basic demonstration of how a user can query current session information by using the SYS_CONTEXT function

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now