Триггер Oracle для обновления объекта в другой таблице

#oracle #triggers

#Oracle #триггеры

Вопрос:

Итак, это из курсовой работы университета, и я впервые работаю с Oracle (и использую триггеры). Предполагается, что мы создаем базу данных для авиакомпании.

Часть базы данных является

 CREATE TABLE FLIGHT_BOOKING (
  BOOKING_ID NUMBER(11) PRIMARY KEY,
  BOOKING_TIME DATE NOT NULL,
  EMPLOYEE_ID NUMBER(11) NOT NULL,
  FLIGHT_ID NUMBER(11) NOT NULL,
  TOTAL_COST NUMBER(4,2) NOT NULL
);

CREATE TABLE FLIGHT (
  FLIGHT_ID NUMBER(11) PRIMARY KEY,
  PLANE_ID NUMBER(11) NOT NULL,
  START_ID NUMBER(11) NOT NULL,
  DESTINATION_ID NUMBER(11) NOT NULL,
  TRANSIT_ID NUMBER(11),
  DEPARTURE_TIME DATE NOT NULL,
  ARRIVAL_TIME DATE NOT NULL,
  NUM_BOOKED NUMBER (4) NOT NULL
);

CREATE TABLE PASSENGER (
  PASSENGER_ID NUMBER(11) PRIMARY KEY,
  FIRST_NAME VARCHAR2(20) NOT NULL,
  MIDDLE_NAME VARCHAR2(20) NULL,
  LAST_NAME VARCHAR2(20) NOT NULL,
  TELEPHONE NUMBER(11) NOT NULL,
  BOOKING_ID NUMBER(11) NOT NULL
);
  

Итак, что я хочу сделать, это создать триггер таким образом, чтобы каждый раз, когда в таблицу PASSENGER добавляется новый пассажир, триггер находил соответствующий FLIGHT_ID из таблицы FLIGHT_BOOKING и увеличивал NUM_BOOKED для соответствующего рейса в таблице FLIGHT.

Я попытался просмотреть документацию Oracle, но не смог найти ничего, что описывает ситуацию, когда речь идет о двух или более таблицах.

Любая помощь была бы очень признательна!

Ответ №1:

вы можете сделать это следующим образом:

 CREATE OR REPLACE TRIGGER update_flight_booking_info
  AFTER INSERT ON PASSENGER
  FOR EACH ROW

DECLARE
    v_flight_id number;
    v_booking_id number;
BEGIN
    v_booking_id  := :new.booking_id ;

    select flight_id into v_flight_id
    from flight_booking
    where booking_id = v_booking_id;

    update flight
    set NUM_BOOKED = NUM_BOOKED   1
    where flight_id = v_flight_id;
END;
  

HTH.

Комментарии:

1. Нет необходимости в отдельном выборе. Вы можете сделать это за одно обновление.

2. @GolezTrol: да, вы абсолютно правы. Tks. Я просто хотел продемонстрировать решение шаг за шагом, что, возможно, имеет смысл.

Ответ №2:

Я бы предпочел не сохранять это число и вычислять его по мере необходимости, но ладно, это просто материал курса. 🙂

Когда вы создаете триггер, внутри него вы можете поместить все виды кода, включая инструкции update.

Итак, вы можете написать триггер, подобный этому:

 create or replace trigger TIDB_BOOKING
before insert or delete
for each row
declare
  V_Increment int;
begin
  -- Inc or dec, depending on insert or update.
  -- Hasn't a booking got a number of seats?
  -- Also, can bookings be updated/moved to other flights?
  -- These problems aren't yet taken into account in this code.
  V_Increment := 1; 
  if deleting then
    V_Increment := -1;

  update FLIGHT f
  set f.NUM_BOOKED = f.NUM_BOOKED   V_Increment
  where f.FLIGHT_ID = nvl(:new.FLIGHT_ID, :old.FLIGHT_ID);
end;