Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Ist dies in Oracle/SQL möglich?

Ein paar Kommentare zu der von Ihnen geposteten DDL.

  • Es gibt kein AUTOINCREMENT Schlüsselwort in Oracle. Sie müssten eine Sequenz erstellen (im Allgemeinen eine Sequenz pro Tabelle) und den NEXTVAL verwenden aus der Sequenz entweder im INSERT -Anweisung selbst oder in einem Trigger, um den synthetischen Primärschlüssel zu füllen.
  • Es gibt nichts, was ein VENUE_NO schafft Spalte in EVENT_DETAILS . Ich nehme an, Ihre tatsächliche DDL definiert diese Spalte.

Sie können dies nicht durch ein einfaches CHECK erzwingen Zwang. Sie können einen Trigger erstellen

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;

Beachten Sie jedoch, dass

  • Sie müssten auch einen Trigger auf VENUE haben Tabelle, die prüft, ob Änderungen an der Kapazität des Veranstaltungsortes dazu führen, dass bestimmte Veranstaltungen ungültig werden. Im Allgemeinen würde dies erfordern, dass die Tabelle mit den Veranstaltungsdetails eine Art Datum enthält, da sich die Kapazität eines Veranstaltungsortes vermutlich im Laufe der Zeit ändern kann und Sie wirklich nur möchten, dass die Validierung nach zukünftigen Veranstaltungen an diesem Veranstaltungsort sucht.
  • Triggerbasierte Lösungen funktionieren nicht immer in Umgebungen mit mehreren Benutzern. Stellen Sie sich vor, Veranstaltungsort 1 hat eine Kapazität von 30. Jetzt aktualisiert Sitzung A diese Kapazität auf 15. Aber bevor Sitzung A festgeschrieben wird, fügt Sitzung B ein Ereignis mit einem NO_PLAYERS ein von 20. Bei keinem der Trigger der Sitzung wird ein Problem angezeigt, sodass beide Änderungen zulässig sind. Aber sobald beide Sessions festgeschrieben sind, wird ein Event mit 20 Spielern an einem Ort gebucht, der nur 15 Spieler unterstützt. Der Trigger auf EVENT_DETAILS könnte möglicherweise die Zeile im VENUE sperren Tabelle, um diese Racebedingung zu vermeiden, aber Sie serialisieren Einfügungen und Aktualisierungen in EVENT_DETAILS -Tabelle, was ein Leistungsproblem darstellen könnte, insbesondere wenn Ihre Anwendung jemals auf menschliche Eingaben wartet, bevor sie eine Transaktion festschreibt.

Als Alternative zu Triggern können Sie einen ON COMMIT erstellen materialisierte Ansicht, die die beiden Tabellen zusammenfügt und ein CHECK setzt Einschränkung dieser materialisierten Ansicht, die die Anforderung erzwingt, dass die Anzahl der Spieler die Kapazität des Veranstaltungsortes nicht überschreiten darf. Das funktioniert in einer Mehrbenutzerumgebung, erfordert aber materialisierte Ansichtsprotokolle für beide Basistabellen und verschiebt die Prüfung an den Punkt, an dem die Sitzungen festgeschrieben werden, was etwas schwierig sein kann. Die meisten Anwendungen berücksichtigen nicht die Möglichkeit, dass ein COMMIT -Anweisung fehlschlagen, sodass die Behandlung dieser Ausnahmen schwierig sein kann. Und aus Sicht der Benutzeroberfläche kann es etwas schwierig sein, dem Benutzer das Problem zu erklären, da sich die Ausnahme auf Änderungen beziehen kann, die viel früher in der Transaktion vorgenommen wurden.