sql >> Databáze >  >> RDS >> Oracle

SQL:spouštěč, který zabrání vložení neplatných dat do tabulky

Příkaz insert může vložit více řádků. Např.:

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;

Tyto vložky se vyskytují v libovolném pořadí, takže nemůžete skutečně přijmout jeden řádek a druhý ne. Místo toho musíte odmítnout celý příkaz insert. Totéž samozřejmě platí pro aktualizace, pokud je lze provést.

V souladu s tím byste napsali spouštěč po příkazu, kde se podíváte na novou situaci v tabulce.

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;

Pokud je tabulka velká a chcete se podívat pouze na vložené/aktualizované řádky, aby tento spouštěč běžel rychle, museli byste místo toho napsat složený spouštěč, kde si zapamatujete ID rezervace v poli na úrovni řádků a budete se dívat pouze na tyto řádky na úrovni příkazu.



  1. Důležité kontroly stavu vašich serverů MySQL se zdrojovými replikami

  2. Mohou modely Django používat funkce MySQL?

  3. Jak vzít vstupy dynamicky vytvořeného textového pole na php a uložit je do MySQL pomocí smyčky?

  4. INSERT INTO ... ON DUPLICATE AKTUALIZUJTE všechny hodnoty