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

Création d'un déclencheur

Ce que vous avez ici est une contrainte de table inter-lignes - c'est-à-dire que vous ne pouvez pas simplement mettre un seul Oracle CONSTRAINT sur une colonne, car ceux-ci ne peuvent consulter que les données d'une seule ligne à la fois.

Oracle ne prend en charge que deux types de contraintes interlignes :l'unicité (par exemple, les clés primaires et les contraintes uniques) et l'intégrité référentielle (clés étrangères).

Dans votre cas, vous devrez coder vous-même la contrainte - et cela s'accompagne de la responsabilité de s'assurer que la contrainte n'est pas violée en présence de plusieurs sessions, dont chacune ne peut pas voir les données insérées/mises à jour par d'autres sessions simultanées (du moins jusqu'à ce qu'ils s'engagent).

Une approche simpliste consiste à ajouter un déclencheur qui émet une requête pour compter le nombre d'enregistrements en conflit avec le nouvel enregistrement ; mais cela ne fonctionnera pas car le déclencheur ne peut pas voir les lignes qui ont été insérées/mises à jour par d'autres sessions mais pas encore validées ; ainsi, le déclencheur permettra parfois aux membres de louer 6 vidéos, à condition (par exemple) qu'ils demandent à deux caissiers de saisir les données dans des terminaux séparés.

Aller simple pour contourner ce problème, il faut mettre un élément de sérialisation - par ex. le déclencheur demandera d'abord un verrou sur l'enregistrement du membre (par exemple avec un SELECT FOR UPDATE) avant d'être autorisé à vérifier les locations ; de cette façon, si une 2ème session essaie d'insérer des locations, elle attendra que la première session fasse un commit ou un rollback.

Une autre façon contourner ce problème consiste à utiliser une vue matérialisée agrégée, qui serait basée sur une requête conçue pour rechercher toutes les lignes qui échouent au test ; l'attente est que le MV sera vide, et vous mettez une contrainte de table sur le MV de telle sorte que si une ligne devait apparaître dans le MV, la contrainte serait violée. L'effet de ceci est que toute instruction qui tente d'insérer des lignes qui violent la contrainte entraînera une violation de contrainte lors de l'actualisation du MV.

Écrire la requête pour cela en fonction de votre conception est laissé comme un exercice pour le lecteur :)