Reputation: 57
I have created a trigger so that when a booking record is inserted or updated, if the evaluation is 0 then details of the booking are inserted into an audit table. The following trigger works perfectly if i update a record, but on insert it gives me the following error:
INSERT INTO "SCOTT"."BOOKING" (PASSENGER_PASSENGER_ID, VOYAGE_VOYAGE_ID, CABIN_NUM, CLASS, EVALUATION) VALUES ('2', '1', '202', 'SECOND', '0')
ORA-01403: no data found
ORA-01403: no data found
ORA-06512: at "SCOTT.EVALUATION_TRIG", line 8
ORA-04088: error during execution of trigger 'SCOTT.EVALUATION_TRIG'
ORA-06512: at line 1
One error saving changes to table "SCOTT"."BOOKING":
Row 2: ORA-01403: no data found
ORA-01403: no data found
ORA-06512: at "SCOTT.EVALUATION_TRIG", line 8
ORA-04088: error during execution of trigger 'SCOTT.EVALUATION_TRIG'
ORA-06512: at line 1
The Oracle SQL Trigger code:
create or replace trigger EVALUATION_TRIG
AFTER INSERT OR UPDATE
ON BOOKING
FOR EACH ROW
WHEN (NEW.EVALUATION =0)
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
PASSENGER_NAME VARCHAR2(30);
CRUISE_NAME VARCHAR2(30);
VOYAGE_DATE DATE;
SHIP_NAME1 VARCHAR2(30);
BEGIN
SELECT NAME INTO PASSENGER_NAME FROM PASSENGER JOIN BOOKING
ON PASSENGER.PASSENGER_ID = BOOKING.PASSENGER_PASSENGER_ID
WHERE BOOKING.PASSENGER_PASSENGER_ID = :NEW.PASSENGER_PASSENGER_ID
AND ROWNUM = 1;
SELECT NAME INTO CRUISE_NAME FROM CRUISE JOIN VOYAGE
ON CRUISE.CRUISE_ID = VOYAGE.CRUISE_CRUISE_ID
JOIN BOOKING ON
VOYAGE.VOYAGE_ID = BOOKING.VOYAGE_VOYAGE_ID
WHERE BOOKING.VOYAGE_VOYAGE_ID = :NEW.VOYAGE_VOYAGE_ID
AND ROWNUM= 1;
SELECT START_DATE INTO VOYAGE_DATE FROM VOYAGE JOIN BOOKING
ON VOYAGE.VOYAGE_ID= BOOKING.VOYAGE_VOYAGE_ID
WHERE BOOKING.VOYAGE_VOYAGE_ID = :NEW.VOYAGE_VOYAGE_ID
AND ROWNUM = 1;
SELECT SHIP_NAME INTO SHIP_NAME1 FROM SHIP JOIN VOYAGE
ON SHIP.SHIP_ID = VOYAGE.SHIP_SHIP_ID JOIN BOOKING
ON VOYAGE.VOYAGE_ID= BOOKING.VOYAGE_VOYAGE_ID
WHERE BOOKING.VOYAGE_VOYAGE_ID = :NEW.VOYAGE_VOYAGE_ID
AND ROWNUM = 1;
INSERT INTO EVALUATION_AUDIT VALUES (PASSENGER_NAME, CRUISE_NAME,VOYAGE_DATE, SHIP_NAME1,:NEW.EVALUATION);
COMMIT;
END;
Upvotes: 2
Views: 9169
Reputation: 116100
That error occurs when you execute a select..into
statement that doesn't return a row, for instance the first one in your trigger.
SELECT NAME INTO PASSENGER_NAME FROM PASSENGER JOIN BOOKING
ON PASSENGER.PASSENGER_ID = BOOKING.PASSENGER_PASSENGER_ID
WHERE BOOKING.PASSENGER_PASSENGER_ID = :NEW.PASSENGER_PASSENGER_ID
AND ROWNUM = 1;
Those :new values should be filled in for inserts just as well as updates, but that doesn't mean that the actual data exists as well.
The query above joins passenger on booking, but if you are inserting the first booking for that passenger, there is no current one. Besides, to get the name of the passenger, you don't need the booking at all. Moreover, querying on a table X in a row level trigger on that same table can give problems.
So, long story short, I think that statement above should look like this:
SELECT NAME INTO PASSENGER_NAME
FROM PASSENGER
WHERE PASSENGER.PASSENGER_ID = :NEW.PASSENGER_PASSENGER_ID;
The same change also needs to be made to the other statements.
After that, you could theoretically still get the same error, but only if :NEW.PASSENGER_PASSENGER_ID doesn't match the id of any passenger. But in that case, I think you should get a foreign key constraint error first, if you have those constraints configured.
I also see a commit in at the end of the trigger. This also doesn't make much sense. The trigger is part of a statement, and the statement itself should be atomic. Committing from the trigger, if this would work at all, would automatically commit each row in multi-row inserts. Suggested reading material.
Upvotes: 3