Kilka komentarzy do DDL, które zamieściłeś.
- Nie ma
AUTOINCREMENT
słowo kluczowe w Oracle. Musisz utworzyć sekwencję (zwykle jedną sekwencję na tabelę) i użyćNEXTVAL
z sekwencji wINSERT
samo oświadczenie lub w wyzwalaczu, aby wypełnić syntetyczny klucz podstawowy. - Nic nie tworzy
VENUE_NO
kolumna wEVENT_DETAILS
. Zakładam, że twój rzeczywisty DDL definiuje tę kolumnę.
Nie możesz tego wymusić za pomocą prostego CHECK
ograniczenie. Możesz utworzyć wyzwalacz
CREATE OR REPLACE TRIGGER validate_capacity
BEFORE INSERT OR UPDATE ON event_details
FOR EACH ROW
DECLARE
l_venue_capacity venue.capacity%type;
BEGIN
SELECT capacity
INTO l_venue_capacity
FROM venue
WHERE venue_no = :new.venue_no;
IF( l_venue_capacity < :new.no_players )
THEN
RAISE_APPLICATION_ERROR( -20001, 'Sorry, the venue has insufficient capacity' );
END IF;
END;
Należy jednak pamiętać, że
- Musisz także mieć wyzwalacz na
VENUE
tabela, która sprawdza, czy zmiany pojemności obiektu powodują, że niektóre wydarzenia stają się nieważne. Ogólnie rzecz biorąc, wymagałoby to, aby w tabeli szczegółów wydarzenia była jakaś data, ponieważ przypuszczalnie pojemność miejsca może się zmieniać w czasie i naprawdę chcesz, aby walidacja sprawdzała tylko przyszłe wydarzenia w tym miejscu. - Rozwiązania oparte na wyzwalaczach nie zawsze będą działać w środowiskach wielu użytkowników. Wyobraź sobie, że miejsce 1 ma pojemność 30. Teraz sesja A aktualizuje tę pojemność do 15. Ale przed zatwierdzeniem sesji A sesja B wstawia zdarzenie z
NO_PLAYERS
z 20. Żaden wyzwalacz sesji nie spowoduje wystąpienia problemu, więc obie zmiany będą dozwolone. Ale gdy obie sesje zostaną zatwierdzone, zostanie zarezerwowane wydarzenie z 20 graczami w miejscu, które obsługuje tylko 15 graczy. Wyzwalacz naEVENT_DETAILS
może potencjalnie zablokować wiersz wVENUE
tabeli, aby uniknąć tego wyścigu, ale serializujesz wstawki i aktualizacje wEVENT_DETAILS
tabeli, która może być problemem z wydajnością, szczególnie jeśli Twoja aplikacja kiedykolwiek czeka na dane wejściowe człowieka przed zatwierdzeniem transakcji.
Jako alternatywę dla wyzwalaczy możesz utworzyć ON COMMIT
zmaterializowany widok, który łączy ze sobą dwie tabele i umieszcza CHECK
ograniczenie tego zmaterializowanego poglądu, który wymusza wymóg, aby liczba graczy nie przekraczała pojemności obiektu. Będzie to działać w środowisku wielu użytkowników, ale wymaga dzienników widoku zmaterializowanego w obu tabelach podstawowych i przenosi kontrolę do punktu, w którym zatwierdzanie sesji może być nieco trudne. Większość aplikacji nie bierze pod uwagę możliwości, że COMMIT
Instrukcja może się nie powieść, więc obsługa tych wyjątków może być trudna. Z punktu widzenia interfejsu użytkownika wyjaśnienie użytkownikowi, na czym polega problem, może być nieco trudne, ponieważ wyjątek może dotyczyć zmian dokonanych znacznie wcześniej w transakcji.