Oracle
 sql >> Base de données >  >> RDS >> Oracle

Est-ce possible dans Oracle/Sql ?

Quelques commentaires sur le DDL que vous avez publié.

  • Il n'y a pas d'AUTOINCREMENT mot-clé dans Oracle. Vous devez créer une séquence (généralement une séquence par table) et utiliser le NEXTVAL de la séquence soit dans le INSERT instruction elle-même ou dans un déclencheur pour remplir la clé primaire synthétique.
  • Il n'y a rien qui crée un VENUE_NO colonne dans EVENT_DETAILS . Je suppose que votre DDL réel définit cette colonne.

Vous ne pouvez pas l'appliquer par un simple CHECK contrainte. Vous pouvez créer un déclencheur

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;

Sachez toutefois que

  • Vous auriez également besoin d'avoir un déclencheur sur le VENUE tableau qui vérifie si les changements de capacité du lieu rendent certains événements invalides. Généralement, cela nécessiterait qu'il y ait une sorte de date dans le tableau des détails de l'événement car, vraisemblablement, la capacité d'un lieu peut changer avec le temps et vous voulez vraiment que la validation vérifie les événements futurs dans ce lieu.
  • Les solutions basées sur des déclencheurs ne fonctionneront pas toujours dans des environnements multi-utilisateurs. Imaginez que le lieu 1 ait une capacité de 30. Maintenant, la session A met à jour cette capacité à 15. Mais avant que la session A ne s'engage, la session B insère un événement avec un NO_PLAYERS de 20. Aucun déclencheur de session ne rencontrera de problème, les deux modifications seront donc autorisées. Mais une fois les deux sessions engagées, il y aura un événement réservé avec 20 joueurs dans un lieu qui ne prend en charge que 15 joueurs. Le déclencheur sur EVENT_DETAILS pourrait potentiellement verrouiller la ligne dans le VENUE table pour éviter cette condition de concurrence, mais vous sérialisez les insertions et les mises à jour sur EVENT_DETAILS table qui pourrait poser un problème de performances, en particulier si votre application attend une intervention humaine avant de valider une transaction.

Comme alternative aux déclencheurs, vous pouvez créer un ON COMMIT vue matérialisée qui joint les deux tables ensemble et met un CHECK contrainte sur cette vue matérialisée qui applique l'exigence selon laquelle le nombre de joueurs ne peut pas dépasser la capacité de la salle. Cela fonctionnera dans un environnement multi-utilisateurs, mais cela nécessite des journaux de vue matérialisés sur les deux tables de base et cela déplace la vérification au point où les sessions sont validées, ce qui peut être un peu délicat. La plupart des applications ne considèrent pas la possibilité qu'un COMMIT L'instruction peut échouer, de sorte que la gestion de ces exceptions peut être délicate. Et du point de vue de l'interface utilisateur, il peut être quelque peu difficile d'expliquer à l'utilisateur quel est le problème puisque l'exception peut concerner des modifications apportées beaucoup plus tôt dans la transaction.