I'm attempting to write a trigger that will disallow any room in a hospital to have more than 3 services. The table RoomServices has a room number and a service that it has. So the only way to determine this is to group the rooms by room number and count the services. I have tried the code:
CREATE TRIGGER RoomServiceLimit
BEFORE INSERT OR UPDATE ON RoomServices
FOR EACH ROW
DECLARE
numService NUMBER;
CURSOR C1 IS SELECT count(*) AS RoomCount FROM RoomServices WHERE roomNumber = :new.roomNumber;
BEGIN
IF(inserting) THEN
SELECT count(*) into numService FROM RoomServices WHERE roomNumber = :new.roomNumber;
if(numService > 2) THEN
RAISE_APPLICATION_ERROR(-20001,'Room ' || :new.roomNumber || ' will have more than 3 services.');
END IF;
END IF;
IF(updating) THEN
FOR rec IN C1 LOOP
IF(rec.RoomCount > 2) THEN
RAISE_APPLICATION_ERROR(-20001,'Room ' || :new.roomNumber || ' will have more than 3 services.');
END IF;
END LOOP;
END IF;
END;
/
I've tried running each method separately with insert and update, and inserting always works and updating will always give me the mutating table error. I don't know how else to go about solving this problem, so any advice would be greatly appreciated.
Thanks!
There is no reliable way to enforce this kind of constraint using triggers. One possible approach is to use a materialized view that automatically refreshes on commit and has a check constraint enforcing your business rule:
Now, whenever you add more than two services for a room and try to commit your transaction, you will get a ORA-12008 exception (error in materialized view refresh path).