Search code examples
sqloracle-databasetriggerssquirrel-sql

"Error: ORA-04098: trigger 'CA0513.ITEMAVGRATINGTRIGGER' is invalid and failed re-validation"


I'm creating a trigger:

CREATE OR REPLACE TRIGGER ItemAvgRatingTrigger
AFTER INSERT OR UPDATE OF rating ON Collectionitems
REFERENCING NEW AS newRow
FOR EACH ROW
BEGIN
    UPDATE Item
    SET rating = (SELECT AVG(Collectionitems.rating) FROM Collectionitems, Item WHERE
        Collectionitems.itemid = newRow.itemid AND newRow.itemid = Item.itemid)
    WHERE Item.itemid = newRow.itemid;
END ItemAvgRatingTrigger;/

Whenver I run the trigger by updating a row in Collectionitems I get squirrel returning this :

Error: ORA-04098: trigger 'CA0513.ITEMAVGRATINGTRIGGER' is invalid and failed re-validation

SQLState:  42000
ErrorCode: 4098
Position: 7

Executing SQL statement:

SELECT * FROM User_Errors;

Generates 1 error:

PLS-00103: Encountered the symbol "/" The symbol "/" was ignored./n

I've read quite a few posts with others having the same problem but haven't found a solution yet, any ideas?


Solution

  • The actual reason for this failing to compile is twofold.

    1. You should reference the new values as :newrow.
    2. You do need a carriage return and/or line feed before /.

    However, this trigger is never going to work. You're going to end up with a mutating table exception, ORA-04091: table name is mutating, trigger/function may not see it. This is because you're referencing the table you're updating in a row level trigger. Simply put Oracle ensures a read-consistent view of the data.

    In the trigger, you're in the middle of updating Collectionitems. Selecting from this table at the same time, in the same session, there are two possible states; updated and not updated. To ensure that your view is read-consistent Oracle raises this error.

    In your particular case you might want to consider a materialized view rather than a trigger.

    Further Reading: