What is problem in my trigger?
I use toad for oracle
After executing this sql toad show this message and no more!:
Warning: compiled but with compilation errors
and trigger does not work
my trigger is here:
CREATE OR REPLACE TRIGGER trg_delete_mmtp_user_feature
BEFORE DELETE
ON mmtp_user
FOR EACH ROW
BEGIN
-- for these cases delete not allowed
IF ((SELECT COUNT (*)
FROM payment p INNER JOIN mmtp_user mt
ON mt.customer_id = p.requester_id
WHERE p.rp_reason_id = 20 AND mt.mmtp_user_id = :OLD.mmtp_user_id) >
0
)
THEN
raise_application_error
(-20654,
'Query has attempted to delete MMTP_USER with existing payment'
);
ELSE --befor deleting features should be deleted
DELETE FROM mmtp_user_feature
WHERE mmtp_user_id = :OLD.mmtp_user_id;
END IF;
END;
/
and for deleting i receive this message:
ORA-04098: trigger 'DEVX2.TRG_DELETE_MMTP_USER_FEATURE' is invalid and failed re-validation
The reason you get a compilation error is that we cannot use SELECT statements in IF clauses. So you need to break it out like this:
Having solved that you will find, as Florin points, that you will get a runtime mutating table error. Oracle throws this error when we put a query in a trigger which accesses the table that owns the trigger. It happens because the table is in an unstable state and the outcome of the query is unpredictable.
Mutating table errors are almost always an indicator of a bad data model, with the culprit being insufficient normalization. That means fixing them requires a knowledge of the business rules. In this case the obvious solution would be:
This would work if there is a one-to-one relationship between
user_idandcustomer_id. It there is not such a relationship you’ll have to figure out a solution using your knowledge of your business rules.Incidentally, using COUNT(*) to test for existence is not a solution which scales. It will take a long time for a customer with many payments. That’s a lot of wasted effort when all you require is that they have at least one such record. Adding
and rownum = 1into the query will reduce the needless work.