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 leNEXTVAL
de la séquence soit dans leINSERT
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 dansEVENT_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 surEVENT_DETAILS
pourrait potentiellement verrouiller la ligne dans leVENUE
table pour éviter cette condition de concurrence, mais vous sérialisez les insertions et les mises à jour surEVENT_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.