Операторът за вмъкване може да вмъкне няколко реда. Напр.:
insert into booking(booking_start, booking_end, booking_room, guest_no)
select date '2019-11-01', date '2019-11-10', 4, 10 from dual
union all
select date '2019-11-08', date '2019-11-15', 4, 88 from dual;
Тези вмъквания се появяват в произволен ред, така че не можете наистина да приемете един ред, а не другия. Вместо това трябва да отхвърлите целия израз за вмъкване. Същото важи и за актуализациите, разбира се, ако такива могат да бъдат направени.
Съответно бихте написали тригер след изявление, където разглеждате новата ситуация в таблицата.
CREATE OR REPLACE TRIGGER trg_reject_invalid_bookings
AFTER INSERT OR UPDATE ON booking
DECLARE
v_count INTEGER;
BEGIN
SELECT count(*)
INTO v_count
FROM booking b1
WHERE EXISTS
(
SELECT *
FROM booking b2
WHERE b2.booking_id <> b1.booking_id
AND b2.booking_room = b1.booking_room
AND b2.booking_start < b1.booking_end
AND b2.booking_end > b1.booking_start
)
AND rownum = 1; -- it suffices to find one overlapping pair
IF v_count > 0 THEN
raise_application_error(-20000, 'Invalid booking');
END IF;
END trg_reject_invalid_bookings;
Ако таблицата е голяма и искате да разглеждате само вмъкнати/актуализирани редове, за да може този тригер да работи бързо, вместо това ще трябва да напишете съставен тригер, където си спомняте идентификаторите на резервация в масив на ниво ред и гледате само тези редове на ниво отчет.