sql >> Database teknologi >  >> RDS >> Oracle

SQL:trigger for at forhindre ugyldige data i at blive indsat i en tabel

En insert-sætning kan indsætte flere rækker. F.eks.:

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;

Disse indsættelser forekommer i vilkårlig rækkefølge, så du kan ikke rigtig acceptere den ene række og ikke den anden. I stedet skal du afvise hele indsættelseserklæringen. Det samme gælder selvfølgelig for opdateringer, hvis sådanne kan laves.

I overensstemmelse hermed ville du skrive en after statement trigger, hvor du ser på den nye situation i tabellen.

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;

Hvis tabellen er stor, og du kun vil se på indsatte/opdaterede rækker for at få denne trigger til at køre hurtigt, skal du i stedet skrive en sammensat trigger, hvor du husker booking-id'er i et array på rækkeniveau og kun ser på disse rækker på erklæringsniveau.



  1. Oracle sql eller pl/sql:Beregn baseret på tidligere rækkeværdier og på datokolonnen

  2. hibernate map java Long til MySQL BIGINT fejl

  3. Slet tomme rækker

  4. hvad er den egentlige årsag til mysql fejl 1442?