2014-12-10 3 views
-1

승객리스트에서 사람을 예약하기 전에 조건이 충족되는지 확인하는 방아쇠를 쓰려고했습니다. 그러나 조건이 충족되지 않을 때, 나는 승객 명단에 삽입하는 것을 금지하고 싶다. 내 방아쇠는 발사되지만 삽입은 무엇이든 상관없이 발생합니다. 이 문제를 어떻게 해결할 수 있습니까? 내가 뭘 잘못하고 있니? 이 조건을 충족하지 않는 경우 예를 들어 INSERT TRIGGER DOESNT STOP INSERT를 삽입하기 전에 PL/SQL

,

INSERT INTO passengerlist_my (flightID, personID, seatnumber) 
    VALUES (1, 5, '43B'); 

위의 삽입 문이 실행됩니다. personID 5 분은 이미. 주심의주의를 받았습니다,하지만 난 삽입 문을 실행할 때, 여전히 문제는 당신의 예외 핸들러는 예외를 먹는 대신에 그들에게 모금을 다시 것입니다

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

여전히 출력 줄을 제공합니까? RAISE 대신 THROW 또는 RAISERROR를 사용하면 효과가 있다고 생각합니다. – Skyl3lazer

+0

네, "그 사람은 이미 예약되었습니다"라고 말하는 적절한 출력 줄을 제공하지만 여전히 테이블에 삽입됩니다. – user3163416

+0

예외를 처리하고 다시 올리지 않으므로 삽입이 방지되지 않습니다. 또한 트리거 코드에서 INSERT 및 COMMIT가 필요하지 않습니다. –

답변

0

를 삽입합니다. 에 예외 처리기를 변경해보십시오 :

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; 

이 예외가 트랜잭션을 롤백 똑똑해야 호출 코드에있는 기존 핸들러에 다시 제기하게됩니다.

공유하고 즐길 수 있습니다.