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

È possibile in Oracle/Sql?

Un paio di commenti sul DDL che hai pubblicato.

  • Non esiste AUTOINCREMENT parola chiave in Oracle. Dovresti creare una sequenza (generalmente una sequenza per tabella) e utilizzare il NEXTVAL dalla sequenza in INSERT istruzione stessa o in un trigger per popolare la chiave primaria sintetica.
  • Non c'è niente che stia creando un VENUE_NO colonna in EVENT_DETAILS . Presumo che il tuo attuale DDL stia definendo quella colonna.

Non puoi imporre questo tramite un semplice CHECK vincolo. Puoi creare un trigger

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;

Tieni presente, tuttavia, che

  • Dovresti anche avere un attivatore su VENUE tabella che verifica se le modifiche alla capacità della sede causano l'annullamento di determinati eventi. In genere, ciò richiederebbe che ci sia una sorta di data nella tabella dei dettagli dell'evento poiché, presumibilmente, la capacità di una sede può cambiare nel tempo e in realtà vuoi solo che la convalida controlli gli eventi futuri in quella sede.
  • Le soluzioni basate su trigger non funzionano sempre in ambienti multiutente. Immagina che la sede 1 abbia una capacità di 30. Ora, la sessione A aggiorna tale capacità a 15. Ma prima che la sessione A si impegni, la sessione B inserisce un evento con un NO_PLAYERS di 20. Nessuno dei trigger di sessione vedrà un problema, quindi entrambe le modifiche saranno consentite. Ma una volta che entrambe le sessioni si impegnano, ci sarà un evento prenotato con 20 giocatori in una sede che supporta solo 15 giocatori. L'attivatore su EVENT_DETAILS potrebbe potenzialmente bloccare la riga in VENUE tabella per evitare questa race condition ma stai serializzando inserti e aggiornamenti su EVENT_DETAILS tabella che potrebbe essere un problema di prestazioni, in particolare se l'applicazione attende l'input umano prima di eseguire una transazione.

In alternativa ai trigger, puoi creare un ON COMMIT vista materializzata che unisce le due tabelle insieme e inserisce un CHECK vincolo su quella visione materializzata che impone il requisito che il numero di giocatori non possa superare la capacità della sede. Funzionerà in un ambiente multiutente, ma richiede registri di visualizzazione materializzati su entrambe le tabelle di base e sposta il controllo al punto in cui le sessioni si impegnano, il che può essere un po' complicato. La maggior parte delle applicazioni non considera la possibilità che un COMMIT istruzione potrebbe non riuscire, quindi gestire tali eccezioni può essere complicato. E dal punto di vista dell'interfaccia utente, può essere alquanto complicato spiegare all'utente qual è il problema poiché l'eccezione potrebbe riguardare modifiche apportate molto prima nella transazione.