Mutating error on after insert trigger

前端 未结 2 1788
无人及你
无人及你 2021-01-22 05:58

The below code is giving a mutating error. Can any1 pls help in solving this.

    CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
    BEFORE INSERT
    ON aso.a         


        
相关标签:
2条回答
  • 2021-01-22 06:33

    I realise you must have resolved your issue by now. However I am adding this answer below to help anyone else facing similar problem as you and I faced.

    I recently encountered mutating table (ORA-04091: table XXXX is mutating, trigger/function may not see it) issue and after searching around realised the Compound Triggers feature available in 11g. If you're on 11g following compound trigger would have solved your issue.

    CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
    FOR INSERT ON aso.aso_quote_headers_all
    COMPOUND TRIGGER
    
        row_id    rowid;
    
        AFTER EACH ROW IS
        BEGIN
          row_id := :new.rowid;
        END AFTER EACH ROW;
    
        AFTER STATEMENT IS
        BEGIN
          UPDATE aso.aso_quote_headers_all 
          SET quote_expiration_date = sysdate+90 
          WHERE rowid = row_id;
        END AFTER STATEMENT;
    END aso_quote_cuhk_trigger;
    /
    

    A word about how it works. This compound trigger fires 2 events :

    1. First is AFTER EACH ROW where we capture the rowid of newly inserted row
    2. Next is AFTER STATEMENT where we update the table using rowid (captured during first event) in the WHERE clause.

    A useful link if you want to read more about Compound Triggers.

    0 讨论(0)
  • 2021-01-22 06:39

    In oracle there are two levels of triggers: row level and table level.

    Row level triggers are executed for each row. Table level triggers executed per statement, even if a statement changed more then one row.
    In a row level trigger, you cannot select/update the table itself that has the trigger: you will get a mutating error.

    In this case, there is no need for an UPDATE statement. Just try this:

    CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
    BEFORE INSERT
    ON aso.aso_quote_headers_all
    FOR EACH ROW
    BEGIN
     :new.quote_expiration_date=sysdate+90;     
    END;
    /
    

    EDIT Rajesh mentioned it is possible, that before inserting a new row, OP wants to update all other records in the aso_quote_headers_all table.

    Well, this is feasible, but it's a little tricky. To do this properly, you will need

    1. A pl/sql package and a variable in the package header that is modified by the triggers. This variable could be a list holding the IDs of newly inserted records. Row level after insert trigger would add a new ID to the list. The content of this package variable will be different for each different session, so let's call this variable session_variable.
    2. Row level after insert trigger, that would add new ID to the session_variable.
    3. Table level after insert trigger that would get IDs from the session_variable, process the ID and then remove it from the session_variable. This trigger could execute necessary selects/updates on the aso_quote_headers_all. After a newly inserted ID is processed, this trigger should make sure it gets removed from the session_variable.
    0 讨论(0)
提交回复
热议问题