Kilka komentarzy do DDL, które zamieściłeś.
- Nie ma
AUTOINCREMENTsłowo kluczowe w Oracle. Musisz utworzyć sekwencję (zwykle jedną sekwencję na tabelę) i użyćNEXTVALz sekwencji wINSERTsamo oświadczenie lub w wyzwalaczu, aby wypełnić syntetyczny klucz podstawowy. - Nic nie tworzy
VENUE_NOkolumna 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
VENUEtabela, 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_PLAYERSz 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_DETAILSmoże potencjalnie zablokować wiersz wVENUEtabeli, aby uniknąć tego wyścigu, ale serializujesz wstawki i aktualizacje wEVENT_DETAILStabeli, 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.