SlideShare une entreprise Scribd logo
1  sur  48
04/08/2022 © Robert Godin. Tous droits réservés. 1
6 Gestion des contraintes
d’intégrité en SQL
 Contrainte d'intégrité statique
– respectée pour chacun des états de la BD
– mécanismes déclaratifs
 PRIMARY KEY, UNIQUE, NOT NULL, DOMAIN, FOREIGN KEY,
CHECK, ASSERTION
– procédural
 TRIGGER (SQL:1999)
 Contrainte d'intégrité dynamique
– contrainte sur changements d'états
– référence aux états successifs
– TRIGGER, REFERENCES ON DELETE…, ON UPDATE ...
04/08/2022 © Robert Godin. Tous droits réservés. 2
6.1Contrainte de domaine
 Types SQL
– INTEGER
– CHAR
– ...
 NOT NULL
 CHECK
 CREATE DOMAIN
04/08/2022 © Robert Godin. Tous droits réservés. 3
6.1.1 Contrainte NOT NULL
 Par défaut : NULL
CREATE TABLE Client
(noCLIENT INTEGER NOT NULL,
nomClient VARCHAR(15) NOT NULL,
noTéléphone VARCHAR(15) NOT NULL
)
04/08/2022 © Robert Godin. Tous droits réservés. 4
6.1.2 Contrainte CHECK
sur une colonne
 Le noClient est supérieur à 0 et inférieur à 100,000
CREATE TABLE Client
(noCLIENT INTEGER NOT NULL
CHECK(noClient >0 AND noClient < 100000),
nomClient VARCHAR(15) NOT NULL,
noTéléphone VARCHAR(15) NOT NULL
)
CREATE TABLE Client
(noCLIENT INTEGER NOT NULL,
nomClient VARCHAR(15) NOT NULL,
noTéléphone VARCHAR(15) NOT NULL,
CHECK(noClient >0 AND noClient < 100000)
)
04/08/2022 © Robert Godin. Tous droits réservés. 5
6.1.3 Création d'un domaine
(CREATE DOMAIN)
CREATE DOMAIN domaineSexe AS
CHAR(1) CHECK(VALUE IN ('M', 'F'))
CREATE TABLE Employé
(codeEmployé INTEGER,
…
sexe domaineSexe,
…
);
CREATE TABLE Client
(noClient INTEGER,
…
sexe domaineSexe,
…
) Pas Oracle...
04/08/2022 © Robert Godin. Tous droits réservés. 6
6.1.4 Valeur de défaut (DEFAULT)
CREATE TABLE Client
(…
noTéléphone VARCHAR(15) DEFAULT 'Confidentiel' NOT NULL
)
04/08/2022 © Robert Godin. Tous droits réservés. 7
6.2 Contrainte de clé
primaire (PRIMARY KEY)
 La clé primaire de la table Client est le noClient
CREATE TABLE Client
(noCLIENT INTEGER PRIMARY KEY
CHECK(noClient >0 AND noClient < 100000),
nomClient VARCHAR(15) NOT NULL,
noTéléphone VARCHAR(15) NOT NULL)
CREATE TABLE Client
(noCLIENT INTEGER NOT NULL,
nomClient VARCHAR(15) NOT NULL,
noTéléphone VARCHAR(15) NOT NULL,
PRIMARY KEY (noCLIENT)
)
04/08/2022 © Robert Godin. Tous droits réservés. 8
Clé primaire composée
CREATE TABLE LigneCommande
(noCommande INTEGER NOT NULL,
noArticle INTEGER NOT NULL,
quantité INTEGER NOT NULL,
PRIMARY KEY (noCommande, noArticle)
)
04/08/2022 © Robert Godin. Tous droits réservés. 9
6.3Autres clés uniques
(UNIQUE)
CREATE Table Citoyen
(noAssurranceSociale INTEGER,
noAssurranceMaladie INTEGER,
noPasseport INTEGER,
nom VARCHAR(30),
prénom VARCHAR(30),
dateNaissance DATE,
noAssSocMère INTEGER,
…
PRIMARY KEY (noAssurranceSociale),
UNIQUE (noAssurranceMaladie),
UNIQUE (noPasseport),
UNIQUE (prénom, noAssSocMère)
)
04/08/2022 © Robert Godin. Tous droits réservés. 10
6.4 Contrainte d'intégrité référentielle
(FOREIGN KEY REFERENCES)
 Le noClient de la table Commande fait référence
à la clé primaire noClient de la table Client
 La table Client doit d ’abord être créée
– privilège REFERENCES sur Client
 PRIMARY KEY ou UNIQUE
CREATE TABLE Commande
(noCommande INTEGER NOT NULL,
dateCommande DATE NOT NULL,
noClient INTEGER NOT NULL,
PRIMARY KEY (noCommande),
FOREIGN KEY (noClient) REFERENCES Client(noClient)
)
04/08/2022 © Robert Godin. Tous droits réservés. 11
6.4.1 Politique de gestion de la
contrainte d'intégrité référentielle
 Tentative de mise à jour de la clé primaire
 Options
– NO ACTION
– CASCADE
– SET NULL
– SET DEFAULT
CREATE TABLE Commande
(noCommande INTEGER NOT NULL,
dateCommande DATE NOT NULL,
noClient INTEGER NOT NULL,
PRIMARY KEY (noCommande),
FOREIGN KEY (noClient) REFERENCES Client(noClient)
)
DELETE FROM Client WHERE noClient = 10
04/08/2022 © Robert Godin. Tous droits réservés. 12
6.4.1.1 Politique NO ACTION
 Rejet d ’une violation de la contrainte
 Clause de défaut Table Commande
noCommande dateCommande noClient
1 01/06/2000 10
2 02/06/2000 20
3 02/06/2000 10
4 05/07/2000 10
5 09/07/2000 30
6 09/07/2000 20
7 15/07/2000 40
8 15/07/2000 40
CREATE TABLE Commande
(noCommande INTEGER NOT NULL,
dateCommande DATE NOT NULL,
noClient INTEGER NOT NULL,
PRIMARY KEY (noCommande),
FOREIGN KEY (noClient) REFERENCES Client
ON DELETE NO ACTION
)
DELETE FROM Client WHERE noClient = 10 {Opération rejetée}
DELETE FROM Client WHERE noClient = 70 {Opération acceptée}
04/08/2022 © Robert Godin. Tous droits réservés. 13
Cas du UPDATE
CREATE TABLE Commande
(noCommande INTEGER NOT NULL,
dateCommande DATE NOT NULL,
noClient INTEGER NOT NULL,
PRIMARY KEY (noCommande),
FOREIGN KEY (noClient) REFERENCES Client
ON UPDATE NO ACTION
)
Table Commande
noCommande dateCommande noClient
1 01/06/2000 10
2 02/06/2000 20
3 02/06/2000 10
4 05/07/2000 10
5 09/07/2000 30
6 09/07/2000 20
7 15/07/2000 40
8 15/07/2000 40
UPDATE Client
SET noClient = 100 WHERE noCLient = 10 {Opération rejetée}
04/08/2022 © Robert Godin. Tous droits réservés. 14
6.4.1.2 Politique CASCADE
 Modification en cascade
CREATE TABLE Commande
(noCommande INTEGER NOT NULL,
dateCommande DATE NOT NULL,
noClient INTEGER NOT NULL,
PRIMARY KEY (noCommande),
FOREIGN KEY (noClient) REFERENCES Client
ON DELETE CASCADE
)
DELETE FROM Client WHERE noClient = 10
{Opération acceptée temporairement}
DELETE FROM Commande WHERE noClient = 10
{Opération déclenchée automatiquement}
04/08/2022 © Robert Godin. Tous droits réservés. 15
ON UPDATE CASCADE
CREATE TABLE Commande
(noCommande INTEGER NOT NULL,
dateCommande DATE NOT NULL,
noClient INTEGER NOT NULL,
PRIMARY KEY (noCommande),
FOREIGN KEY (noClient) REFERENCES Client
ON UPDATE CASCADE
)
UPDATE Client
SET noClient = 100 WHERE noCLient = 10
{Opération acceptée temporairement}
UPDATE Commande
SET noClient = 100 WHERE noCLient = 10
{Opération déclenchée automatiquement}
04/08/2022 © Robert Godin. Tous droits réservés. 16
6.4.1.3 Politiques SET
NULL et SET DEFAULT
CREATE TABLE Commande
(noCommande INTEGER NOT NULL,
dateCommande DATE NOT NULL,
noClient INTEGER NOT NULL,
PRIMARY KEY (noCommande),
FOREIGN KEY (noClient) REFERENCES Client
ON DELETE SET NULL
)
DELETE FROM Client WHERE noClient = 10
{Opération acceptée temporairement}
UPDATE Commande
SET noClient = NULL WHERE noCLient = 10
{Opération déclenchée automatiquement}
04/08/2022 © Robert Godin. Tous droits réservés. 17
SET DEFAULT
CREATE TABLE Commande
(noCommande INTEGER NOT NULL,
dateCommande DATE NOT NULL,
noClient INTEGER DEFAULT 50 NOT NULL,
PRIMARY KEY (noCommande),
FOREIGN KEY (noClient) REFERENCES Client
ON DELETE SET DEFAULT
)
DELETE FROM Client WHERE noClient = 10
{Opération acceptée temporairement}
UPDATE Commande
SET noClient = 50 WHERE noCLient = 10
{Opération déclenchée automatiquement}
04/08/2022 © Robert Godin. Tous droits réservés. 18
6.4.1.4 Clause MATCH
PARTIAL/FULL
CREATE TABLE DétailLivraison
(noLivraison INTEGER NOT NULL,
noCommande INTEGER NOT NULL,
noArticle INTEGER,
quantitéLivrée INTEGER,
PRIMARY KEY (noLivraison,noCommande, noArticle),
FOREIGN KEY (noLivraison) REFERENCES Livraison(noLivraison),
FOREIGN KEY (noCommande, noArticle) REFERENCES
LigneCommande MACTH PARTIAL
)
Table LigneCommande
noCommande noArticle quantité
1 10 10
1 70 5
1 90 1
2 40 2
2 95 3
3 20 1
4 40 1
4 50 1
5 70 3
5 10 5
5 20 5
6 10 5
6 40 1
7 50 1
7 95 2
8 20 3
INSERT INTO DétailLivraison(noLivraison, noCommande)
VALUES (105, 4) {Opération acceptée}
INSERT INTO DétailLivraison(noLivraison, noCommande)
VALUES (105, 10) {Opération rejetée}
04/08/2022 © Robert Godin. Tous droits réservés. 19
Oracle
 Défaut
– ON DELETE NO ACTION
– ON UPDATE NO ACTION
 Supporte aussi
– ON DELETE CASCADE
– ON DELETE SET NULL (version 8i)
04/08/2022 © Robert Godin. Tous droits réservés. 20
6.5 Autres contraintes
 CHECK au delà d ’une colonne
 ASSERTION générale
04/08/2022 © Robert Godin. Tous droits réservés. 21
6.5.1 CHECK intra-ligne
 Plusieurs colonnes de la même ligne
 Les Articles dont le noArticle est supérieur à 90
ont un prix supérieur à $15.00
CREATE TABLE Article
(noArticle INTEGER NOT NULL,
description VARCHAR(20),
prixUnitaire DECIMAL(10,2) NOT NULL,
quantitéEnStock INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (noArticle),
CHECK (noArticle <=90 OR prixUnitaire > 15.0)
)
04/08/2022 © Robert Godin. Tous droits réservés. 22
6.5.2 Check inter-ligne
d'une même table
 Concerne plusieurs lignes
 Le prixUnitaire d'un Article ne peut dépasser le prix
moyen de plus de $40.00
 Vérifié uniquement pour la ligne touchée
– La contrainte peut être violée !
 Pas supporté par Oracle
CREATE TABLE Article
(noArticle INTEGER NOT NULL,
description VARCHAR(20),
prixUnitaire DECIMAL(10,2) NOT NULL,
quantitéEnStock INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (noArticle),
CHECK (prixUnitaire-20 <= (SELECT AVG(prixUnitaire)
FROM Article))
)
04/08/2022 © Robert Godin. Tous droits réservés. 23
6.5.3 CHECK inter-tables
 Concerne plusieurs tables
 Vérifié uniquement pour la ligne touchée
– La contrainte peut être violée !
 Pas supporté par Oracle
P rê t
{C lé p rim a ire : id P rê t}
id P rê t
d a te P rê t
id M e m b re
<< T a b le > >
P rê tArc h ivé
{C lé p rim a ire : id P rê t}
id P rê t
d a te R e to u r
id E xe m p la ire
< < T a b le > >
CREATE TABLE PrêtArchivé
(idPrêt INTEGER NOT NULL,
dateRetour DATE NOT NULL,
idExemplaire INTEGER NOT NULL,
PRIMARY KEY (idPrêt),
FOREIGN KEY (idPrêt) REFERENCES Prêt,
CHECK (dateRetour >=
SELECT datePrêt
FROM Prêt
WHERE Prêt.idPrêt = PrêtArchivé.idPrêt)
)
04/08/2022 © Robert Godin. Tous droits réservés. 24
6.5.4 Assertions générales
 Le prixUnitaire moyen d'un Article ne peut
dépasser $25.00
 Toujours valide par opposition au CHECK
 Non supporté par Oracle
CREATE ASSERTION assertionPrixMoyenMaximal CHECK
(25 >= SELECT AVG(prixUnitaire)
FROM Article)
04/08/2022 © Robert Godin. Tous droits réservés. 25
Assertion inter-tables
 La somme des quantitéLivrées pour une
LigneCommande ne peut dépasser la quantité
commandée
CREATE ASSERTION assertionQuantitéLivrée
(NOT EXISTS(
SELECT *
FROM LigneCommande AS L, DétailLivraison AS D
WHERE L.noArticle = D.noArticle AND
L.noCommande = D.noCommande
GROUP BY L.noCommande, L.noArticle, quantité
HAVING quantité < SUM(quantitéLivrée)))
04/08/2022 © Robert Godin. Tous droits réservés. 26
6.6 Implémentation de la vérification
des contraintes d'intégrité
 Problème non trivial
 Vérifier uniquement les lignes modifiées
 Simplification différentielle
 Simplification sémantique
– mécanismes d ’inférence
04/08/2022 © Robert Godin. Tous droits réservés. 27
6.7 Cohérence des
contraintes d'intégrité
 Impossible de mettre à jour Article avec :
 Problème difficile en général
 Aucune ou peu de vérification dans les
SGBD actuels
CREATE TABLE Article
(noArticle INTEGER NOT NULL,
description VARCHAR(20),
prixUnitaire DECIMAL(10,2) NOT NULL,
quantitéEnStock INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (noArticle),
CHECK (prixUnitaire > 15.0 AND prixUnitaire < 15.0))
04/08/2022 © Robert Godin. Tous droits réservés. 28
6.8 Nom de contrainte
(clause CONSTRAINT)
 DROP CONSTRAINT contNoClient
 SET CONSTRAINT contNoClient …
 Identification de la contrainte qui est violée à
l ’exécution
CREATE TABLE Client
(noCLIENT INTEGER NOT NULL,
nomClient VARCHAR(15) NOT NULL,
noTéléphone VARCHAR(15) NOT NULL,
CONSTRAINT contNoClient CHECK(noClient >0 AND noClient < 100000)
)
04/08/2022 © Robert Godin. Tous droits réservés. 29
6.9 Contraintes déférées (SET
CONSTRAINTS DEFERRED)
 Quand vérifier ?
 Une Commande ne peut exister sans LigneCommande associée
 Vérification immédiate par défaut
– impossible d ’ajouter une Commande + ses LigneCommandes …
CREATE ASSERTION assertionCommandeVide CHECK
(NOT EXISTS
(SELECT *
FROM Commande
WHERE noCommande NOT IN
(SELECT noCommande
FROM LigneCommande)
04/08/2022 © Robert Godin. Tous droits réservés. 30
Clause DEFERRABLE
 Solution au problème :
 Ou INITIALLY DEFERRED
SET CONSTRAINTS assertionCommandeVide DEFERRED
CREATE ASSERTION assertionCommandeVide CHECK
(NOT EXISTS
(SELECT *
FROM Commande
WHERE noCommande NOT IN
(SELECT noCommande
FROM LigneCommande)
)DEFERRABLE INITIALLY IMMEDIATE
04/08/2022 © Robert Godin. Tous droits réservés. 31
6.10 Gâchettes
(TRIGGER)
 Procédure
– déclenchée par événement pré-déterminé (INSERT, DELETE, UPDATE)
– exécutée au niveau serveur de BD
 BD active
 Utilité
– maintien de contraintes d ’intégrité
 statique
 dynamique
 alternative aux mécanismes déclaratifs (CHECK, ASSERTION, ...)
– préférer mécanisme déclaratif
– maintien d ’éléments dérivés
 colonnes dérivées
 copies dans BD répartie
 ...
– historique des mises à jour
 AUDIT
– sécurité
04/08/2022 © Robert Godin. Tous droits réservés. 32
Lorsqu'une augmentation du prixUnitaire d'un Article
est tentée, il faut limiter l'augmentation à 10% du prix
en cours
CREATE TRIGGER BUArticleBornerAugmentationPrix
BEFORE UPDATE OF prixUnitaire ON Article
REFERENCING
OLD ROW AS ligneAvant
NEW ROW AS ligneAprès
FOR EACH ROW
WHEN (ligneAprès.prixUnitaire > ligneAvant.prixUnitaire*1.1)
BEGIN
ligneAprès.prixUnitaire = ligneAvant.prixUnitaire*1.1;
END
UPDATE Article
SET prixUnitaire = 15.99
WHERE noArticle = 10
10 Cèdre en boule 10.99
noArticle description prixUnitaire
ligneAvant
10 Cèdre en boule 15.99
ligneAprès 10 Cèdre en boule 12.09
ligneAprès
04/08/2022 © Robert Godin. Tous droits réservés. 33
6.10.1 Utilisation d'un TRIGGER
pour le maintien d'une contrainte
d'intégrité dynamique
 Empêcher une augmentation du prixUnitaire
d'un Article au delà de 10% du prix en cours
 Oracle
– RAISE_APPLICATION_ERROR
CREATE TRIGGER BUArticleEmpêcherAugmentationPrixTropElevée
BEFORE UPDATE OF prixUnitaire ON Article
REFERENCING
OLD ROW AS ligneAvant
NEW ROW AS ligneAprès
FOR EACH ROW
WHEN (ligneAprès.prixUnitaire > ligneAvant.prixUnitaire*1.1)
BEGIN
souleverUneException;
END
04/08/2022 © Robert Godin. Tous droits réservés. 34
6.10.2 Utilisation d'un TRIGGER pour le
maintien d'une contrainte d'intégrité statique
 0 < noClient < 100000
 N.B. CHECK est préférable !
CREATE TRIGGER BIUClientVérifierNoClient
BEFORE INSERT OR UPDATE OF noClient ON Client
REFERENCING
NEW ROW AS ligneAprès
FOR EACH ROW
WHEN (ligneAprès.noClient <=0) OR
(ligneAprès.noClient > 100000)
BEGIN
souleverUneException;
END
04/08/2022 © Robert Godin. Tous droits réservés. 35
6.10.3 Étude de cas
 Lors d'une nouvelle livraison, la quantité à livrer ne
peut dépasser la quantité en stock disponible
CREATE TRIGGER BIDétLivVérifierQuantitéEnStock
BEFORE INSERT ON DétailLivraison
REFERENCING
NEW ROW AS ligneAprès
FOR EACH ROW
WHEN ligneAprès.quantitéLivrée >
(SELECT quantitéEnStock
FROM Article
WHERE noArticle = ligneAprès.noArticle)
BEGIN
souleverUneException;
END
04/08/2022 © Robert Godin. Tous droits réservés. 36
CHECK SQL2 inadéquat
CREATE TABLE DétailLivraison
(noLivraison INTEGER NOT NULL,
noCommande INTEGER NOT NULL,
noArticle INTEGER NOT NULL,
quantitéLivrée INTEGER NOT NULL,
PRIMARY KEY (noLivraison,noCommande, noArticle),
FOREIGN KEY (noLivraison) REFERENCES Livraison(noLivraison),
FOREIGN KEY (noCommande, noArticle) REFERENCES
LigneCommande(noCommande, noArticle),
CHECK (0 <=
SELECT quantitéEnStock-quantitéLivrée
FROM Article
WHERE noArticle = DétailLivraison.noArticle)
)
04/08/2022 © Robert Godin. Tous droits réservés. 37
Lors d'une modification d'une quantitéLivrée, la
différence entre la nouvelle quantitéLivrée et
l'ancienne quantitéeLivrée doit être inférieure ou
égale à la quantitéEnStock
CREATE TRIGGER BUDétLivVérifierQuantitéEnStock
BEFORE UPDATE OF quantitéLivrée ON DétailLivraison
REFERENCING
OLD ROW AS ligneAvant
NEW ROW AS ligneAprès
FOR EACH ROW
WHEN ligneAprès.quantitéLivrée-ligneAvant.quantitéLivrée >
(SELECT quantitéEnStock
FROM Article
WHERE noArticle = ligneAvant.noArticle)
BEGIN
souleverUneException;
END
04/08/2022 © Robert Godin. Tous droits réservés. 38
Ne permettre que la modification
de la quantitéLivrée dans la table
DétailLiraison
CREATE TRIGGER BUDétLivEmpêcherModif
BEFORE UPDATE OF noLivraison, noCommande, noArticle
ON DétailLivraison
BEGIN
souleverUneException;
END
04/08/2022 © Robert Godin. Tous droits réservés. 39
Ajuster la
quantitéEnStock
CREATE TRIGGER AIDétLivAjusterQuantitéEnStock
AFTER INSERT ON DétailLivraison
REFERENCING
NEW ROW AS ligneAprès
FOR EACH ROW
BEGIN
UPDATE Article
SET quantitéEnStock = quantitéEnStock -
ligneAprès.quantitéLivrée
WHERE noArticle = ligneAprès.noArticle;
END
CREATE TRIGGER AUDétLivAjusterQuantitéEnStock
AFTER UPDATE OF quantitéLivrée ON DétailLivraison
REFERENCING
OLD ROW AS ligneAvant
NEW ROW AS ligneAprès
FOR EACH ROW
BEGIN
UPDATE Article
SET quantitéEnStock = quantitéEnStock -
(ligneAprès.quantitéLivrée-ligneAvant.quantitéLivrée)
WHERE noArticle = ligneAvant.noArticle;
END
04/08/2022 © Robert Godin. Tous droits réservés. 40
Extension procédurale
pour corpsTrigger
 Traitements complexes
 Combiner plusieurs TRIGGER
– vérifier quel est l ’événement déclencheur
 Ordre d ’exécution des TRIGGER
– BEFORE avant AFTER,...
– entre TRIGGER de même type ?
 forcer un ordre en combinant
 Oracle
– PL/SQL
04/08/2022 © Robert Godin. Tous droits réservés. 41
6.10.4 TRIGGER de
niveau STATEMENT
 Exécution du corps une seule fois pour
plusieurs lignes mises à jours dans le même
énoncé
CREATE TRIGGER BUDétLivEmpêcherModif
BEFORE UPDATE OF noLivraison, noCommande, noArticle
ON DétailLivraison
BEGIN
souleverUneException;
END
REFERENCING
OLD TABLE AS nomAvant
NEW TABLE AS nomAprès
04/08/2022 © Robert Godin. Tous droits réservés. 42
Exécuter les TRIGGER BEFORE STATEMENT
Pour chaque ligne touchée par l'opération
Exécuter les TRIGGER BEFORE ROW
Exécuter l'opération
Exécuter les TRIGGER AFTER ROW
Fin pour
Exécuter les TRIGGER AFTER STATEMENT
6.10.5 Ordre d'exécution
des TRIGGER
 Attention aux circularités !
04/08/2022 © Robert Godin. Tous droits réservés. 43
6.10.6 Limites des TRIGGER
 Ne peuvent être DEFERRED
 Complexes à coder
 Contraintes particulières aux dialectes
04/08/2022 © Robert Godin. Tous droits réservés. 44
6.10.7 Particularités des
TRIGGER Oracle
 Pas de SELECT dans le WHEN
 :NEW, :OLD
 Omettre le mot-clé ROW dans REFERENCING
 Corps en PL/SQL (voir chapitre 4).
 Syntaxe :nomColonne
 Pas de COMMIT/ROLLBACK dans un TRIGGER
– procédure PL/SQL RAISE_APPLICATION_ERROR
 Intervalle [-20000, -20999] pour code d’erreur
 IF INSERTING, DELETING, UPDATING.
 Événements non standards
– INSTEAD OF, STARTUP, LOGON, ...
 Problème avec table en mutation (modifiée par l'événement déclencheur)
 etc.
SQL> CREATE OR REPLACE TRIGGER BUArticleBornerAugPrix
2 BEFORE UPDATE OF prixUnitaire ON Article
3 REFERENCING
4 OLD AS ligneAvant
5 NEW AS ligneAprès
6 FOR EACH ROW
7 WHEN (ligneAprès.prixUnitaire > ligneAvant.prixUnitaire*1.1)
8 BEGIN
9 :ligneAprès.prixUnitaire := :ligneAvant.prixUnitaire*1.1;
10 END;
11 /
Déclencheur créé.
SQL> -- Test du TRIGGER BUArticleBornerAugPrix
SQL> SELECT * FROM Article WHERE noArticle = 10
2 /
NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK
--------- -------------------- ------------ ---------------
10 Cèdre en boule 10,99 10
SQL> UPDATE Article
2 SET prixUnitaire = 15.99
3 WHERE noArticle = 10
4 /
1 ligne mise à jour.
SQL> SELECT * FROM Article WHERE noArticle = 10
2 /
NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK
--------- -------------------- ------------ ---------------
10 Cèdre en boule 12,09 10
SQL> CREATE OR REPLACE TRIGGER BIDétLivVérifierStock
2 BEFORE INSERT ON DétailLivraison
3 REFERENCING
4 NEW AS ligneAprès
5 FOR EACH ROW
6 DECLARE
7 laQuantitéEnStock INTEGER;
8 -- N.B. Oracle ne supporte pas de SELECT dans le WHEN
9 -- Il faut donc utiliser un IF PL/SQL
10 BEGIN
11 SELECT quantitéEnStock
12 INTO laQuantitéEnStock
13 FROM Article
14 WHERE noArticle = :ligneAprès.noArticle;
15
16 IF :ligneAprès.quantitéLivrée > laQuantitéEnStock THEN
17 raise_application_error(-20100, 'stock disponible insuffisant');
18 END IF;
19 END;
20 /
Déclencheur créé.
SQL> -- Test du TRIGGER BIDétLivVérifierStock
SQL> SELECT * FROM Article WHERE noArticle = 10
2 /
NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK
--------- -------------------- ------------ ---------------
10 Cèdre en boule 12,09 10
SQL> INSERT INTO DétailLivraison
2 VALUES(105,5,10,30)
3 /
INSERT INTO DétailLivraison
*
ERREUR à la ligne 1:
ORA-20100: stock disponible insuffisant
ORA-06512: à "BANQUE.BIDÉTLIVVÉRIFIERSTOCK", ligne 12
ORA-04088: erreur lors d'exécution du déclencheur 'BANQUE.BIDÉTLIVVÉRIFIERSTOCK'
04/08/2022 © Robert Godin. Tous droits réservés. 47
Trigger INSTEAD OF pour VIEW non
modifiable (non standard SQL:1999)
SQL> SELECT * FROM Article WHERE noArticle = 10
2 /
NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK
---------- -------------------- ------------ ---------------
10 Cèdre en boule 10,99 20
SQL> CREATE VIEW ArticlePrixPlusTaxe AS
2 SELECT noArticle, description, prixUnitaire * 1.15 AS prixPlusTaxe
3 FROM Article
4 /
View created.
SQL> UPDATE ArticlePrixPlusTaxe
2 SET prixPlusTaxe = 23
3 WHERE noArticle = 10
4 /
SET prixPlusTaxe = 23
*
ERROR at line 2:
ORA-01733: virtual column not allowed here
04/08/2022 © Robert Godin. Tous droits réservés. 48
suite
SQL> CREATE OR REPLACE TRIGGER InsteadUpdate
2 INSTEAD OF UPDATE ON ArticlePrixPlusTaxe
3 REFERENCING
4 OLD AS ligneAvant
5 NEW AS ligneAprès
6 FOR EACH ROW
7 BEGIN
8 UPDATE Article
9 SET
10 noArticle = :ligneAprès.noArticle,
11 description = :ligneAprès.description,
12 prixUnitaire = :ligneAprès.prixPlusTaxe / 1.15
13 WHERE noArticle = :ligneAvant.noArticle;
14 END;
15 /
Trigger created.
SQL> UPDATE ArticlePrixPlusTaxe
2 SET prixPlusTaxe = 23
3 WHERE noArticle = 10
4 /
1 row updated.
SQL> SELECT * FROM Article WHERE noArticle = 10
2 /
NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK
---------- -------------------- ------------ ---------------
10 Cèdre en boule 20 20

Contenu connexe

Dernier

Bilan énergétique des chambres froides.pdf
Bilan énergétique des chambres froides.pdfBilan énergétique des chambres froides.pdf
Bilan énergétique des chambres froides.pdf
AmgdoulHatim
 
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptxCopie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
ikospam0
 

Dernier (19)

Apolonia, Apolonia.pptx Film documentaire
Apolonia, Apolonia.pptx         Film documentaireApolonia, Apolonia.pptx         Film documentaire
Apolonia, Apolonia.pptx Film documentaire
 
Bilan énergétique des chambres froides.pdf
Bilan énergétique des chambres froides.pdfBilan énergétique des chambres froides.pdf
Bilan énergétique des chambres froides.pdf
 
Neuvaine de la Pentecôte avec des textes de saint Jean Eudes
Neuvaine de la Pentecôte avec des textes de saint Jean EudesNeuvaine de la Pentecôte avec des textes de saint Jean Eudes
Neuvaine de la Pentecôte avec des textes de saint Jean Eudes
 
python-Cours Officiel POO Python-m103.pdf
python-Cours Officiel POO Python-m103.pdfpython-Cours Officiel POO Python-m103.pdf
python-Cours Officiel POO Python-m103.pdf
 
Les roches magmatique géodynamique interne.pptx
Les roches magmatique géodynamique interne.pptxLes roches magmatique géodynamique interne.pptx
Les roches magmatique géodynamique interne.pptx
 
L application de la physique classique dans le golf.pptx
L application de la physique classique dans le golf.pptxL application de la physique classique dans le golf.pptx
L application de la physique classique dans le golf.pptx
 
Formation qhse - GIASE saqit_105135.pptx
Formation qhse - GIASE saqit_105135.pptxFormation qhse - GIASE saqit_105135.pptx
Formation qhse - GIASE saqit_105135.pptx
 
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projet
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projetFormation échiquéenne jwhyCHESS, parallèle avec la planification de projet
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projet
 
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
 
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANK
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANKRAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANK
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANK
 
Cours Généralités sur les systèmes informatiques
Cours Généralités sur les systèmes informatiquesCours Généralités sur les systèmes informatiques
Cours Généralités sur les systèmes informatiques
 
L'expression du but : fiche et exercices niveau C1 FLE
L'expression du but : fiche et exercices  niveau C1 FLEL'expression du but : fiche et exercices  niveau C1 FLE
L'expression du but : fiche et exercices niveau C1 FLE
 
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptx
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptxIntégration des TICE dans l'enseignement de la Physique-Chimie.pptx
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptx
 
Echos libraries Burkina Faso newsletter 2024
Echos libraries Burkina Faso newsletter 2024Echos libraries Burkina Faso newsletter 2024
Echos libraries Burkina Faso newsletter 2024
 
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...
 
les_infections_a_streptocoques.pptkioljhk
les_infections_a_streptocoques.pptkioljhkles_infections_a_streptocoques.pptkioljhk
les_infections_a_streptocoques.pptkioljhk
 
Conférence Sommet de la formation 2024 : Développer des compétences pour la m...
Conférence Sommet de la formation 2024 : Développer des compétences pour la m...Conférence Sommet de la formation 2024 : Développer des compétences pour la m...
Conférence Sommet de la formation 2024 : Développer des compétences pour la m...
 
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptxCopie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
 
Télécommunication et transport .pdfcours
Télécommunication et transport .pdfcoursTélécommunication et transport .pdfcours
Télécommunication et transport .pdfcours
 

En vedette

Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
Kurio // The Social Media Age(ncy)
 

En vedette (20)

AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 

Chap6.ppt

  • 1. 04/08/2022 © Robert Godin. Tous droits réservés. 1 6 Gestion des contraintes d’intégrité en SQL  Contrainte d'intégrité statique – respectée pour chacun des états de la BD – mécanismes déclaratifs  PRIMARY KEY, UNIQUE, NOT NULL, DOMAIN, FOREIGN KEY, CHECK, ASSERTION – procédural  TRIGGER (SQL:1999)  Contrainte d'intégrité dynamique – contrainte sur changements d'états – référence aux états successifs – TRIGGER, REFERENCES ON DELETE…, ON UPDATE ...
  • 2. 04/08/2022 © Robert Godin. Tous droits réservés. 2 6.1Contrainte de domaine  Types SQL – INTEGER – CHAR – ...  NOT NULL  CHECK  CREATE DOMAIN
  • 3. 04/08/2022 © Robert Godin. Tous droits réservés. 3 6.1.1 Contrainte NOT NULL  Par défaut : NULL CREATE TABLE Client (noCLIENT INTEGER NOT NULL, nomClient VARCHAR(15) NOT NULL, noTéléphone VARCHAR(15) NOT NULL )
  • 4. 04/08/2022 © Robert Godin. Tous droits réservés. 4 6.1.2 Contrainte CHECK sur une colonne  Le noClient est supérieur à 0 et inférieur à 100,000 CREATE TABLE Client (noCLIENT INTEGER NOT NULL CHECK(noClient >0 AND noClient < 100000), nomClient VARCHAR(15) NOT NULL, noTéléphone VARCHAR(15) NOT NULL ) CREATE TABLE Client (noCLIENT INTEGER NOT NULL, nomClient VARCHAR(15) NOT NULL, noTéléphone VARCHAR(15) NOT NULL, CHECK(noClient >0 AND noClient < 100000) )
  • 5. 04/08/2022 © Robert Godin. Tous droits réservés. 5 6.1.3 Création d'un domaine (CREATE DOMAIN) CREATE DOMAIN domaineSexe AS CHAR(1) CHECK(VALUE IN ('M', 'F')) CREATE TABLE Employé (codeEmployé INTEGER, … sexe domaineSexe, … ); CREATE TABLE Client (noClient INTEGER, … sexe domaineSexe, … ) Pas Oracle...
  • 6. 04/08/2022 © Robert Godin. Tous droits réservés. 6 6.1.4 Valeur de défaut (DEFAULT) CREATE TABLE Client (… noTéléphone VARCHAR(15) DEFAULT 'Confidentiel' NOT NULL )
  • 7. 04/08/2022 © Robert Godin. Tous droits réservés. 7 6.2 Contrainte de clé primaire (PRIMARY KEY)  La clé primaire de la table Client est le noClient CREATE TABLE Client (noCLIENT INTEGER PRIMARY KEY CHECK(noClient >0 AND noClient < 100000), nomClient VARCHAR(15) NOT NULL, noTéléphone VARCHAR(15) NOT NULL) CREATE TABLE Client (noCLIENT INTEGER NOT NULL, nomClient VARCHAR(15) NOT NULL, noTéléphone VARCHAR(15) NOT NULL, PRIMARY KEY (noCLIENT) )
  • 8. 04/08/2022 © Robert Godin. Tous droits réservés. 8 Clé primaire composée CREATE TABLE LigneCommande (noCommande INTEGER NOT NULL, noArticle INTEGER NOT NULL, quantité INTEGER NOT NULL, PRIMARY KEY (noCommande, noArticle) )
  • 9. 04/08/2022 © Robert Godin. Tous droits réservés. 9 6.3Autres clés uniques (UNIQUE) CREATE Table Citoyen (noAssurranceSociale INTEGER, noAssurranceMaladie INTEGER, noPasseport INTEGER, nom VARCHAR(30), prénom VARCHAR(30), dateNaissance DATE, noAssSocMère INTEGER, … PRIMARY KEY (noAssurranceSociale), UNIQUE (noAssurranceMaladie), UNIQUE (noPasseport), UNIQUE (prénom, noAssSocMère) )
  • 10. 04/08/2022 © Robert Godin. Tous droits réservés. 10 6.4 Contrainte d'intégrité référentielle (FOREIGN KEY REFERENCES)  Le noClient de la table Commande fait référence à la clé primaire noClient de la table Client  La table Client doit d ’abord être créée – privilège REFERENCES sur Client  PRIMARY KEY ou UNIQUE CREATE TABLE Commande (noCommande INTEGER NOT NULL, dateCommande DATE NOT NULL, noClient INTEGER NOT NULL, PRIMARY KEY (noCommande), FOREIGN KEY (noClient) REFERENCES Client(noClient) )
  • 11. 04/08/2022 © Robert Godin. Tous droits réservés. 11 6.4.1 Politique de gestion de la contrainte d'intégrité référentielle  Tentative de mise à jour de la clé primaire  Options – NO ACTION – CASCADE – SET NULL – SET DEFAULT CREATE TABLE Commande (noCommande INTEGER NOT NULL, dateCommande DATE NOT NULL, noClient INTEGER NOT NULL, PRIMARY KEY (noCommande), FOREIGN KEY (noClient) REFERENCES Client(noClient) ) DELETE FROM Client WHERE noClient = 10
  • 12. 04/08/2022 © Robert Godin. Tous droits réservés. 12 6.4.1.1 Politique NO ACTION  Rejet d ’une violation de la contrainte  Clause de défaut Table Commande noCommande dateCommande noClient 1 01/06/2000 10 2 02/06/2000 20 3 02/06/2000 10 4 05/07/2000 10 5 09/07/2000 30 6 09/07/2000 20 7 15/07/2000 40 8 15/07/2000 40 CREATE TABLE Commande (noCommande INTEGER NOT NULL, dateCommande DATE NOT NULL, noClient INTEGER NOT NULL, PRIMARY KEY (noCommande), FOREIGN KEY (noClient) REFERENCES Client ON DELETE NO ACTION ) DELETE FROM Client WHERE noClient = 10 {Opération rejetée} DELETE FROM Client WHERE noClient = 70 {Opération acceptée}
  • 13. 04/08/2022 © Robert Godin. Tous droits réservés. 13 Cas du UPDATE CREATE TABLE Commande (noCommande INTEGER NOT NULL, dateCommande DATE NOT NULL, noClient INTEGER NOT NULL, PRIMARY KEY (noCommande), FOREIGN KEY (noClient) REFERENCES Client ON UPDATE NO ACTION ) Table Commande noCommande dateCommande noClient 1 01/06/2000 10 2 02/06/2000 20 3 02/06/2000 10 4 05/07/2000 10 5 09/07/2000 30 6 09/07/2000 20 7 15/07/2000 40 8 15/07/2000 40 UPDATE Client SET noClient = 100 WHERE noCLient = 10 {Opération rejetée}
  • 14. 04/08/2022 © Robert Godin. Tous droits réservés. 14 6.4.1.2 Politique CASCADE  Modification en cascade CREATE TABLE Commande (noCommande INTEGER NOT NULL, dateCommande DATE NOT NULL, noClient INTEGER NOT NULL, PRIMARY KEY (noCommande), FOREIGN KEY (noClient) REFERENCES Client ON DELETE CASCADE ) DELETE FROM Client WHERE noClient = 10 {Opération acceptée temporairement} DELETE FROM Commande WHERE noClient = 10 {Opération déclenchée automatiquement}
  • 15. 04/08/2022 © Robert Godin. Tous droits réservés. 15 ON UPDATE CASCADE CREATE TABLE Commande (noCommande INTEGER NOT NULL, dateCommande DATE NOT NULL, noClient INTEGER NOT NULL, PRIMARY KEY (noCommande), FOREIGN KEY (noClient) REFERENCES Client ON UPDATE CASCADE ) UPDATE Client SET noClient = 100 WHERE noCLient = 10 {Opération acceptée temporairement} UPDATE Commande SET noClient = 100 WHERE noCLient = 10 {Opération déclenchée automatiquement}
  • 16. 04/08/2022 © Robert Godin. Tous droits réservés. 16 6.4.1.3 Politiques SET NULL et SET DEFAULT CREATE TABLE Commande (noCommande INTEGER NOT NULL, dateCommande DATE NOT NULL, noClient INTEGER NOT NULL, PRIMARY KEY (noCommande), FOREIGN KEY (noClient) REFERENCES Client ON DELETE SET NULL ) DELETE FROM Client WHERE noClient = 10 {Opération acceptée temporairement} UPDATE Commande SET noClient = NULL WHERE noCLient = 10 {Opération déclenchée automatiquement}
  • 17. 04/08/2022 © Robert Godin. Tous droits réservés. 17 SET DEFAULT CREATE TABLE Commande (noCommande INTEGER NOT NULL, dateCommande DATE NOT NULL, noClient INTEGER DEFAULT 50 NOT NULL, PRIMARY KEY (noCommande), FOREIGN KEY (noClient) REFERENCES Client ON DELETE SET DEFAULT ) DELETE FROM Client WHERE noClient = 10 {Opération acceptée temporairement} UPDATE Commande SET noClient = 50 WHERE noCLient = 10 {Opération déclenchée automatiquement}
  • 18. 04/08/2022 © Robert Godin. Tous droits réservés. 18 6.4.1.4 Clause MATCH PARTIAL/FULL CREATE TABLE DétailLivraison (noLivraison INTEGER NOT NULL, noCommande INTEGER NOT NULL, noArticle INTEGER, quantitéLivrée INTEGER, PRIMARY KEY (noLivraison,noCommande, noArticle), FOREIGN KEY (noLivraison) REFERENCES Livraison(noLivraison), FOREIGN KEY (noCommande, noArticle) REFERENCES LigneCommande MACTH PARTIAL ) Table LigneCommande noCommande noArticle quantité 1 10 10 1 70 5 1 90 1 2 40 2 2 95 3 3 20 1 4 40 1 4 50 1 5 70 3 5 10 5 5 20 5 6 10 5 6 40 1 7 50 1 7 95 2 8 20 3 INSERT INTO DétailLivraison(noLivraison, noCommande) VALUES (105, 4) {Opération acceptée} INSERT INTO DétailLivraison(noLivraison, noCommande) VALUES (105, 10) {Opération rejetée}
  • 19. 04/08/2022 © Robert Godin. Tous droits réservés. 19 Oracle  Défaut – ON DELETE NO ACTION – ON UPDATE NO ACTION  Supporte aussi – ON DELETE CASCADE – ON DELETE SET NULL (version 8i)
  • 20. 04/08/2022 © Robert Godin. Tous droits réservés. 20 6.5 Autres contraintes  CHECK au delà d ’une colonne  ASSERTION générale
  • 21. 04/08/2022 © Robert Godin. Tous droits réservés. 21 6.5.1 CHECK intra-ligne  Plusieurs colonnes de la même ligne  Les Articles dont le noArticle est supérieur à 90 ont un prix supérieur à $15.00 CREATE TABLE Article (noArticle INTEGER NOT NULL, description VARCHAR(20), prixUnitaire DECIMAL(10,2) NOT NULL, quantitéEnStock INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (noArticle), CHECK (noArticle <=90 OR prixUnitaire > 15.0) )
  • 22. 04/08/2022 © Robert Godin. Tous droits réservés. 22 6.5.2 Check inter-ligne d'une même table  Concerne plusieurs lignes  Le prixUnitaire d'un Article ne peut dépasser le prix moyen de plus de $40.00  Vérifié uniquement pour la ligne touchée – La contrainte peut être violée !  Pas supporté par Oracle CREATE TABLE Article (noArticle INTEGER NOT NULL, description VARCHAR(20), prixUnitaire DECIMAL(10,2) NOT NULL, quantitéEnStock INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (noArticle), CHECK (prixUnitaire-20 <= (SELECT AVG(prixUnitaire) FROM Article)) )
  • 23. 04/08/2022 © Robert Godin. Tous droits réservés. 23 6.5.3 CHECK inter-tables  Concerne plusieurs tables  Vérifié uniquement pour la ligne touchée – La contrainte peut être violée !  Pas supporté par Oracle P rê t {C lé p rim a ire : id P rê t} id P rê t d a te P rê t id M e m b re << T a b le > > P rê tArc h ivé {C lé p rim a ire : id P rê t} id P rê t d a te R e to u r id E xe m p la ire < < T a b le > > CREATE TABLE PrêtArchivé (idPrêt INTEGER NOT NULL, dateRetour DATE NOT NULL, idExemplaire INTEGER NOT NULL, PRIMARY KEY (idPrêt), FOREIGN KEY (idPrêt) REFERENCES Prêt, CHECK (dateRetour >= SELECT datePrêt FROM Prêt WHERE Prêt.idPrêt = PrêtArchivé.idPrêt) )
  • 24. 04/08/2022 © Robert Godin. Tous droits réservés. 24 6.5.4 Assertions générales  Le prixUnitaire moyen d'un Article ne peut dépasser $25.00  Toujours valide par opposition au CHECK  Non supporté par Oracle CREATE ASSERTION assertionPrixMoyenMaximal CHECK (25 >= SELECT AVG(prixUnitaire) FROM Article)
  • 25. 04/08/2022 © Robert Godin. Tous droits réservés. 25 Assertion inter-tables  La somme des quantitéLivrées pour une LigneCommande ne peut dépasser la quantité commandée CREATE ASSERTION assertionQuantitéLivrée (NOT EXISTS( SELECT * FROM LigneCommande AS L, DétailLivraison AS D WHERE L.noArticle = D.noArticle AND L.noCommande = D.noCommande GROUP BY L.noCommande, L.noArticle, quantité HAVING quantité < SUM(quantitéLivrée)))
  • 26. 04/08/2022 © Robert Godin. Tous droits réservés. 26 6.6 Implémentation de la vérification des contraintes d'intégrité  Problème non trivial  Vérifier uniquement les lignes modifiées  Simplification différentielle  Simplification sémantique – mécanismes d ’inférence
  • 27. 04/08/2022 © Robert Godin. Tous droits réservés. 27 6.7 Cohérence des contraintes d'intégrité  Impossible de mettre à jour Article avec :  Problème difficile en général  Aucune ou peu de vérification dans les SGBD actuels CREATE TABLE Article (noArticle INTEGER NOT NULL, description VARCHAR(20), prixUnitaire DECIMAL(10,2) NOT NULL, quantitéEnStock INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (noArticle), CHECK (prixUnitaire > 15.0 AND prixUnitaire < 15.0))
  • 28. 04/08/2022 © Robert Godin. Tous droits réservés. 28 6.8 Nom de contrainte (clause CONSTRAINT)  DROP CONSTRAINT contNoClient  SET CONSTRAINT contNoClient …  Identification de la contrainte qui est violée à l ’exécution CREATE TABLE Client (noCLIENT INTEGER NOT NULL, nomClient VARCHAR(15) NOT NULL, noTéléphone VARCHAR(15) NOT NULL, CONSTRAINT contNoClient CHECK(noClient >0 AND noClient < 100000) )
  • 29. 04/08/2022 © Robert Godin. Tous droits réservés. 29 6.9 Contraintes déférées (SET CONSTRAINTS DEFERRED)  Quand vérifier ?  Une Commande ne peut exister sans LigneCommande associée  Vérification immédiate par défaut – impossible d ’ajouter une Commande + ses LigneCommandes … CREATE ASSERTION assertionCommandeVide CHECK (NOT EXISTS (SELECT * FROM Commande WHERE noCommande NOT IN (SELECT noCommande FROM LigneCommande)
  • 30. 04/08/2022 © Robert Godin. Tous droits réservés. 30 Clause DEFERRABLE  Solution au problème :  Ou INITIALLY DEFERRED SET CONSTRAINTS assertionCommandeVide DEFERRED CREATE ASSERTION assertionCommandeVide CHECK (NOT EXISTS (SELECT * FROM Commande WHERE noCommande NOT IN (SELECT noCommande FROM LigneCommande) )DEFERRABLE INITIALLY IMMEDIATE
  • 31. 04/08/2022 © Robert Godin. Tous droits réservés. 31 6.10 Gâchettes (TRIGGER)  Procédure – déclenchée par événement pré-déterminé (INSERT, DELETE, UPDATE) – exécutée au niveau serveur de BD  BD active  Utilité – maintien de contraintes d ’intégrité  statique  dynamique  alternative aux mécanismes déclaratifs (CHECK, ASSERTION, ...) – préférer mécanisme déclaratif – maintien d ’éléments dérivés  colonnes dérivées  copies dans BD répartie  ... – historique des mises à jour  AUDIT – sécurité
  • 32. 04/08/2022 © Robert Godin. Tous droits réservés. 32 Lorsqu'une augmentation du prixUnitaire d'un Article est tentée, il faut limiter l'augmentation à 10% du prix en cours CREATE TRIGGER BUArticleBornerAugmentationPrix BEFORE UPDATE OF prixUnitaire ON Article REFERENCING OLD ROW AS ligneAvant NEW ROW AS ligneAprès FOR EACH ROW WHEN (ligneAprès.prixUnitaire > ligneAvant.prixUnitaire*1.1) BEGIN ligneAprès.prixUnitaire = ligneAvant.prixUnitaire*1.1; END UPDATE Article SET prixUnitaire = 15.99 WHERE noArticle = 10 10 Cèdre en boule 10.99 noArticle description prixUnitaire ligneAvant 10 Cèdre en boule 15.99 ligneAprès 10 Cèdre en boule 12.09 ligneAprès
  • 33. 04/08/2022 © Robert Godin. Tous droits réservés. 33 6.10.1 Utilisation d'un TRIGGER pour le maintien d'une contrainte d'intégrité dynamique  Empêcher une augmentation du prixUnitaire d'un Article au delà de 10% du prix en cours  Oracle – RAISE_APPLICATION_ERROR CREATE TRIGGER BUArticleEmpêcherAugmentationPrixTropElevée BEFORE UPDATE OF prixUnitaire ON Article REFERENCING OLD ROW AS ligneAvant NEW ROW AS ligneAprès FOR EACH ROW WHEN (ligneAprès.prixUnitaire > ligneAvant.prixUnitaire*1.1) BEGIN souleverUneException; END
  • 34. 04/08/2022 © Robert Godin. Tous droits réservés. 34 6.10.2 Utilisation d'un TRIGGER pour le maintien d'une contrainte d'intégrité statique  0 < noClient < 100000  N.B. CHECK est préférable ! CREATE TRIGGER BIUClientVérifierNoClient BEFORE INSERT OR UPDATE OF noClient ON Client REFERENCING NEW ROW AS ligneAprès FOR EACH ROW WHEN (ligneAprès.noClient <=0) OR (ligneAprès.noClient > 100000) BEGIN souleverUneException; END
  • 35. 04/08/2022 © Robert Godin. Tous droits réservés. 35 6.10.3 Étude de cas  Lors d'une nouvelle livraison, la quantité à livrer ne peut dépasser la quantité en stock disponible CREATE TRIGGER BIDétLivVérifierQuantitéEnStock BEFORE INSERT ON DétailLivraison REFERENCING NEW ROW AS ligneAprès FOR EACH ROW WHEN ligneAprès.quantitéLivrée > (SELECT quantitéEnStock FROM Article WHERE noArticle = ligneAprès.noArticle) BEGIN souleverUneException; END
  • 36. 04/08/2022 © Robert Godin. Tous droits réservés. 36 CHECK SQL2 inadéquat CREATE TABLE DétailLivraison (noLivraison INTEGER NOT NULL, noCommande INTEGER NOT NULL, noArticle INTEGER NOT NULL, quantitéLivrée INTEGER NOT NULL, PRIMARY KEY (noLivraison,noCommande, noArticle), FOREIGN KEY (noLivraison) REFERENCES Livraison(noLivraison), FOREIGN KEY (noCommande, noArticle) REFERENCES LigneCommande(noCommande, noArticle), CHECK (0 <= SELECT quantitéEnStock-quantitéLivrée FROM Article WHERE noArticle = DétailLivraison.noArticle) )
  • 37. 04/08/2022 © Robert Godin. Tous droits réservés. 37 Lors d'une modification d'une quantitéLivrée, la différence entre la nouvelle quantitéLivrée et l'ancienne quantitéeLivrée doit être inférieure ou égale à la quantitéEnStock CREATE TRIGGER BUDétLivVérifierQuantitéEnStock BEFORE UPDATE OF quantitéLivrée ON DétailLivraison REFERENCING OLD ROW AS ligneAvant NEW ROW AS ligneAprès FOR EACH ROW WHEN ligneAprès.quantitéLivrée-ligneAvant.quantitéLivrée > (SELECT quantitéEnStock FROM Article WHERE noArticle = ligneAvant.noArticle) BEGIN souleverUneException; END
  • 38. 04/08/2022 © Robert Godin. Tous droits réservés. 38 Ne permettre que la modification de la quantitéLivrée dans la table DétailLiraison CREATE TRIGGER BUDétLivEmpêcherModif BEFORE UPDATE OF noLivraison, noCommande, noArticle ON DétailLivraison BEGIN souleverUneException; END
  • 39. 04/08/2022 © Robert Godin. Tous droits réservés. 39 Ajuster la quantitéEnStock CREATE TRIGGER AIDétLivAjusterQuantitéEnStock AFTER INSERT ON DétailLivraison REFERENCING NEW ROW AS ligneAprès FOR EACH ROW BEGIN UPDATE Article SET quantitéEnStock = quantitéEnStock - ligneAprès.quantitéLivrée WHERE noArticle = ligneAprès.noArticle; END CREATE TRIGGER AUDétLivAjusterQuantitéEnStock AFTER UPDATE OF quantitéLivrée ON DétailLivraison REFERENCING OLD ROW AS ligneAvant NEW ROW AS ligneAprès FOR EACH ROW BEGIN UPDATE Article SET quantitéEnStock = quantitéEnStock - (ligneAprès.quantitéLivrée-ligneAvant.quantitéLivrée) WHERE noArticle = ligneAvant.noArticle; END
  • 40. 04/08/2022 © Robert Godin. Tous droits réservés. 40 Extension procédurale pour corpsTrigger  Traitements complexes  Combiner plusieurs TRIGGER – vérifier quel est l ’événement déclencheur  Ordre d ’exécution des TRIGGER – BEFORE avant AFTER,... – entre TRIGGER de même type ?  forcer un ordre en combinant  Oracle – PL/SQL
  • 41. 04/08/2022 © Robert Godin. Tous droits réservés. 41 6.10.4 TRIGGER de niveau STATEMENT  Exécution du corps une seule fois pour plusieurs lignes mises à jours dans le même énoncé CREATE TRIGGER BUDétLivEmpêcherModif BEFORE UPDATE OF noLivraison, noCommande, noArticle ON DétailLivraison BEGIN souleverUneException; END REFERENCING OLD TABLE AS nomAvant NEW TABLE AS nomAprès
  • 42. 04/08/2022 © Robert Godin. Tous droits réservés. 42 Exécuter les TRIGGER BEFORE STATEMENT Pour chaque ligne touchée par l'opération Exécuter les TRIGGER BEFORE ROW Exécuter l'opération Exécuter les TRIGGER AFTER ROW Fin pour Exécuter les TRIGGER AFTER STATEMENT 6.10.5 Ordre d'exécution des TRIGGER  Attention aux circularités !
  • 43. 04/08/2022 © Robert Godin. Tous droits réservés. 43 6.10.6 Limites des TRIGGER  Ne peuvent être DEFERRED  Complexes à coder  Contraintes particulières aux dialectes
  • 44. 04/08/2022 © Robert Godin. Tous droits réservés. 44 6.10.7 Particularités des TRIGGER Oracle  Pas de SELECT dans le WHEN  :NEW, :OLD  Omettre le mot-clé ROW dans REFERENCING  Corps en PL/SQL (voir chapitre 4).  Syntaxe :nomColonne  Pas de COMMIT/ROLLBACK dans un TRIGGER – procédure PL/SQL RAISE_APPLICATION_ERROR  Intervalle [-20000, -20999] pour code d’erreur  IF INSERTING, DELETING, UPDATING.  Événements non standards – INSTEAD OF, STARTUP, LOGON, ...  Problème avec table en mutation (modifiée par l'événement déclencheur)  etc.
  • 45. SQL> CREATE OR REPLACE TRIGGER BUArticleBornerAugPrix 2 BEFORE UPDATE OF prixUnitaire ON Article 3 REFERENCING 4 OLD AS ligneAvant 5 NEW AS ligneAprès 6 FOR EACH ROW 7 WHEN (ligneAprès.prixUnitaire > ligneAvant.prixUnitaire*1.1) 8 BEGIN 9 :ligneAprès.prixUnitaire := :ligneAvant.prixUnitaire*1.1; 10 END; 11 / Déclencheur créé. SQL> -- Test du TRIGGER BUArticleBornerAugPrix SQL> SELECT * FROM Article WHERE noArticle = 10 2 / NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK --------- -------------------- ------------ --------------- 10 Cèdre en boule 10,99 10 SQL> UPDATE Article 2 SET prixUnitaire = 15.99 3 WHERE noArticle = 10 4 / 1 ligne mise à jour. SQL> SELECT * FROM Article WHERE noArticle = 10 2 / NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK --------- -------------------- ------------ --------------- 10 Cèdre en boule 12,09 10
  • 46. SQL> CREATE OR REPLACE TRIGGER BIDétLivVérifierStock 2 BEFORE INSERT ON DétailLivraison 3 REFERENCING 4 NEW AS ligneAprès 5 FOR EACH ROW 6 DECLARE 7 laQuantitéEnStock INTEGER; 8 -- N.B. Oracle ne supporte pas de SELECT dans le WHEN 9 -- Il faut donc utiliser un IF PL/SQL 10 BEGIN 11 SELECT quantitéEnStock 12 INTO laQuantitéEnStock 13 FROM Article 14 WHERE noArticle = :ligneAprès.noArticle; 15 16 IF :ligneAprès.quantitéLivrée > laQuantitéEnStock THEN 17 raise_application_error(-20100, 'stock disponible insuffisant'); 18 END IF; 19 END; 20 / Déclencheur créé. SQL> -- Test du TRIGGER BIDétLivVérifierStock SQL> SELECT * FROM Article WHERE noArticle = 10 2 / NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK --------- -------------------- ------------ --------------- 10 Cèdre en boule 12,09 10 SQL> INSERT INTO DétailLivraison 2 VALUES(105,5,10,30) 3 / INSERT INTO DétailLivraison * ERREUR à la ligne 1: ORA-20100: stock disponible insuffisant ORA-06512: à "BANQUE.BIDÉTLIVVÉRIFIERSTOCK", ligne 12 ORA-04088: erreur lors d'exécution du déclencheur 'BANQUE.BIDÉTLIVVÉRIFIERSTOCK'
  • 47. 04/08/2022 © Robert Godin. Tous droits réservés. 47 Trigger INSTEAD OF pour VIEW non modifiable (non standard SQL:1999) SQL> SELECT * FROM Article WHERE noArticle = 10 2 / NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK ---------- -------------------- ------------ --------------- 10 Cèdre en boule 10,99 20 SQL> CREATE VIEW ArticlePrixPlusTaxe AS 2 SELECT noArticle, description, prixUnitaire * 1.15 AS prixPlusTaxe 3 FROM Article 4 / View created. SQL> UPDATE ArticlePrixPlusTaxe 2 SET prixPlusTaxe = 23 3 WHERE noArticle = 10 4 / SET prixPlusTaxe = 23 * ERROR at line 2: ORA-01733: virtual column not allowed here
  • 48. 04/08/2022 © Robert Godin. Tous droits réservés. 48 suite SQL> CREATE OR REPLACE TRIGGER InsteadUpdate 2 INSTEAD OF UPDATE ON ArticlePrixPlusTaxe 3 REFERENCING 4 OLD AS ligneAvant 5 NEW AS ligneAprès 6 FOR EACH ROW 7 BEGIN 8 UPDATE Article 9 SET 10 noArticle = :ligneAprès.noArticle, 11 description = :ligneAprès.description, 12 prixUnitaire = :ligneAprès.prixPlusTaxe / 1.15 13 WHERE noArticle = :ligneAvant.noArticle; 14 END; 15 / Trigger created. SQL> UPDATE ArticlePrixPlusTaxe 2 SET prixPlusTaxe = 23 3 WHERE noArticle = 10 4 / 1 row updated. SQL> SELECT * FROM Article WHERE noArticle = 10 2 / NOARTICLE DESCRIPTION PRIXUNITAIRE QUANTITÉENSTOCK ---------- -------------------- ------------ --------------- 10 Cèdre en boule 20 20