我尝试编写一个触发器,在允许某个人在乘客名单上预订之前检查以确保满足条件。但是当条件不满足时,我想禁止插入乘客名单。我的触发器触发,但插入发生在任何地方。我该如何解决这个问题?我做错了什么?
例如,
INSERT INTO passengerlist_my (flightID, personID, seatnumber)
VALUES (1, 5, '43B');
上述插入语句在不满足条件时执行。 personID 5的人已被预订。但是当我运行insert语句时,它仍会插入
SET serveroutput ON
/
CREATE OR REPLACE TRIGGER bookpersons
BEFORE INSERT ON passengerlist_my
FOR EACH ROW
DECLARE
--declaration section
checkflight number;
bookedseats number;
planecapacity number;
chkpbooked number;
FLIGHT_IS_FULL EXCEPTION;
PERSON_IS_BOOKED EXCEPTION;
querystr VARCHAR2(255) := 'INSERT INTO passengerlist_my (flightID, personID, seatnumber)
VALUES (:NEW.flightID, :NEW.personID, :NEW.seatnumber)';
BEGIN
--check IF FLIGHT exists
SELECT COUNT(*) INTO checkflight FROM FLIGHT WHERE flightID = :NEW.flightID;
IF checkflight<1 THEN
RAISE_APPLICATION_ERROR(-2000, 'Flight doesnt Exist');
END IF;
--check booked seats
SELECT COUNT(*) INTO bookedseats FROM passengerlist WHERE flightID = :NEW.flightID;
--check plane capacity
SELECT NUMBEROFSEATS INTO planecapacity FROM PLANETYPE
JOIN PLANE USING (PLANETYPEID)
JOIN FLIGHT USING (PLANEID)
WHERE flightID = :NEW.flightID;
--check if person is already booked
SELECT COUNT(*) INTO chkpbooked
FROM PASSENGERLIST_MY
WHERE FLIGHTID = :NEW.flightID AND personID = :NEW.personID;
IF chkpbooked>=1 THEN
RAISE PERSON_IS_BOOKED;
END IF;
IF bookedseats>=planecapacity THEN
RAISE FLIGHT_IS_FULL;
END IF;
INSERT INTO passengerlist_my (flightID, personID, seatnumber)
VALUES (:NEW.flightID, :NEW.personID, :NEW.seatnumber);
COMMIT;
EXCEPTION
WHEN FLIGHT_IS_FULL THEN
DBMS_OUTPUT.PUT_LINE('This flight is FULL. Passenger cannot be booked!');
WHEN PERSON_IS_BOOKED THEN
DBMS_OUTPUT.PUT_LINE('Person is already booked!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error Occured. Passenger cannot be booked!');
END;
/
答案 0 :(得分:1)
问题是你的异常处理程序正在吃异常而不是重新提升它们。尝试将异常处理程序更改为:
EXCEPTION
WHEN FLIGHT_IS_FULL THEN
DBMS_OUTPUT.PUT_LINE('This flight is FULL. Passenger cannot be booked!');
RAISE;
WHEN PERSON_IS_BOOKED THEN
DBMS_OUTPUT.PUT_LINE('Person is already booked!');
RAISE;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error Occured. Passenger cannot be booked!');
RAISE;
这将导致异常重新引发到调用代码中的任何现有处理程序,该处理程序应该足够智能以回滚事务。
分享并享受。