CONTRAINTES D INTÉGRITÉ EN SQL 1/32 Classes de contraintes Contraintes structurelles (rappel Domaine Unicité Référence Contraintes applicatives Conditions que doit vérifier un sous ensemble de la BD pour maintenir la cohérence des informations 2/32 1
Contraintes générales, contraintes de tables Contraintes générales Portent sur une ou plusieurs colonnes de plusieurs tables Opérations coûteuses Vérifiées après chaque mise à jour Contraintes attachées à une table Ne peut exister sans table!! Disparaissent avec la table Une nouvelle contrainte est rejetée si elle n est pas en accord avec les valeurs déjà présentes dans la base 3/32 Assertion: syntaxe creer_contrainte_generale ::= CREATE ASSERTION nom_contrainte CHECK (condition Supprimer_contrainte_generale ::= DROP ASSERTION nom_contrainte ; 4/32 2
Assertion: syntaxe contrainte_table ::= [CONSTRAINT nom] type_contrainte_table mode_contrainte type_contrainte_table ::= PRIMARY KEY (nom_colonne + NOT NULL (nom_colonne + UNIQUE (nom_colonne + CHECK (condition FOREIGN KEY (nom_colonne + REFERENCES nom_table (nom_colonne + mode_contrainte ::= [NOT] DEFERRABLE Evaluée au moment de la MAJ Evaluée au moment du COMMIT 5/32 Assertion: exemples Contrainte générale CREATE ASSERTION a_salaire CHECK ( NOT EXISTS (SELECT * FROM employe WHERE SALAIRE > 4000 AND e.num_service <> (SELECT num_service FROM service WHERE nom= direction Il ne doit pas exister de salaire > 4000 ailleurs que dans le service direction 6/32 3
Assertion: exemples Contrainte de table CREATE TABLE employe ( numero d_numero primary key, nom d_nom NOT NULL, prenom d_prenom, adresse d_adressse, num_service d_numero, salaire d_salaire, taxe d_taxe, constraint salaire_taxe check (salaire>taxe not deferrable Contrainte horizontale salaire et taxe appartiennent au même tuple 7/32 Assertion: exemples Contrainte de table (suite CREATE TABLE employe ( numero d_numero primary key, nom d_nom NOT NULL, prenom d_prenom, adresse d_adressse, num_service d_numero, salaire d_salaire, taxe d_taxe, constraint salaire_coherent check (salaire < 2 * (select avg(salaire from employe e where e.num_service= employe.num_service not deferrable Contrainte verticale le salaire est contrôléen fonction de ses valeurs sur les autres tuples 9/32 4
Assertion: exemples Contrainte de table (suite CREATE TABLE employe ( numero d_numero primary key, nom d_nom NOT NULL, prenom d_prenom, adresse d_adressse, num_service d_numero, salaire d_salaire, taxe d_taxe, constraint salaire_informaticien check (2500 <= 2 * (select avg(salaire from employe where num_service = (select num_service from service where nom= informatique not deferrable Contrainte en référence à une autre table Attention à l ordre de création et de chargement des tables 11/32 Assertion: exemples Contrainte de table (suite CREATE TABLE qualification ( numero d_numero_qualif primary key, nom d_qualification CREATE TABLE possede_qualif ( numero_qualif d_numero_qualif, numero_employe d_numero, primary key (numero_qualif, numero_employe, foreign key (numero_qualif references qualification (numero, foreign key (numero_employe references employe (numero 13/32 5
Assertion: exemples Contrainte de table (suite CREATE TABLE employe ( numero d_numero primary key, nom d_nom NOT NULL, prenom d_prenom, adresse d_adressse, num_service d_numero, salaire d_salaire, taxe d_taxe, constraint nombre_qualification check (1<= (select count (* from employe, possede_qualif where numero = numero_employe deferrable Contrainte en référence à une autre table Attention à l ordre de création et de chargement des tables 14/32 Assertion: exemples Contrainte de table (suite CREATE TABLE comptable ( numero_employe d_numero_qualif primary key, prime d_prime CREATE TABLE commercial ( numero_employe d_numero_qualif primary key, pourcentage_vente d_pourcentage 16/32 6
Assertion: exemples Contrainte de table (suite CREATE TABLE employe ( numero d_numero primary key, nom d_nom NOT NULL, prenom d_prenom, adresse d_adressse, num_service d_numero, salaire d_salaire, taxe d_taxe, constraint nombre_qualification check (1 = (select count (* from employe, comptable cp, commercial cm where numero = cp.numero_employe or numero = cm.numero_employe deferrable Contrainte en référence à une autre table Attention à l ordre de création et de chargement des tables 17/32 Déclencheurs Déclencheur (trigger Un déclencheur est une règle, dite active, de la forme : événement - condition action L action est déclenchée à la suite de l événement ET si la condition est vérifiée. Une action peut être: une vérification une mise àjour. Un événement est une mise àjour 19/32 7
Déclencheurs Définition d un déclencheur Evénement: INSERT, UPDATE, DELETE nom de la relation [, nom des attributs mis àjour] moment de l action: avant, aprèsou àla place de la mise àjour nommer l ancien (suppression et le nouveau tuple (insertion condition booléenne optionnelle qui déclenche l événement: placée dans le WHEN action àréaliser sous la forme requête SQL ; action réalisée pour chaque tuple mis àjour ou une seule fois pour la requête. 20/32 Déclencheurs commande ::= CREATE TRIGGER nominstant_de_déclenchementévénement [nommage][condition] action ; instant_de_déclenchement ::= BEFORE AFTER INSTEAD OF événement ::= (INSERT DELETE UPDATE [OF liste de nom_de_colonne] ON nom_de_table nommage ::= REFERENCING (OLD AS nom NEW AS nom condition ::= WHEN expression_booléenne action ::= (liste de commande [FOR EACH (ROW STATEMENT] 21/32 8
Déclencheurs: exemples CREATE TRIGGER incr_nb_employe AFTER INSERT ON employe (UPDATE service SET nb_emp = nb_emp +1 WHERE num_service = employe.num_service CREATE TRIGGER dec_nb_employe BEFORE DELETE ON employe (UPDATE service SET nb_emp = nb_emp - 1 WHERE num_service = employe.num_service 22/32 Déclencheurs: exemples CREATE TRIGGER maj_nb_employe BEFORE UPDATE OF num_service ON employe REFERENCING OLD AS old_emp NEW AS new_emp (UPDATE service SET nb_emp = nb_emp + 1 WHERE num_service = new_emp.num_service, UPDATE service SET nb_emp = nb_emp - 1 WHERE num_service = old_emp.num_service 24/32 9
Déclencheurs: exemples CREATE TRIGGER big_brother_ins AFTER INSERT ON employe (INSERT INTO journal SELECT USER, CURRENT_TIMESTAMP, insert, e.numero, e.nom,, e.taxe FROM employe e WHERE e.numero = employe.numero 26/32 Déclencheurs: exemples CREATE TRIGGER big_brother_del BEFORE DELETE ON employe (INSERT INTO journal SELECT USER, CURRENT_TIMESTAMP, delete, e.numero, e.nom,, e.taxe FROM employe e WHERE e.numero = employe.numero 28/32 10
Déclencheurs: exemples CREATE TRIGGER big_brother_upd BEFORE UPDATE ON employe REFERENCING OLD AS old_emp NEW AS new_emp (INSERT INTO journal SELECT USER, CURRENT_TIMESTAMP, old, e.numero, e.nom,, e.taxe FROM employe e WHERE e.numero = old_emp.numero, INSERT INTO journal SELECT USER, CURRENT_TIMESTAMP, new, e.numero, e.nom,, e.taxe FROM employe e WHERE e.numero = new_emp.numero 30/32 Déclencheurs: exemples CREATE TRIGGER maj_salaire AFTER UPDATE OF salaire ON employe REFERENCING OLD AS ancien NEW AS nouveau WHEN USER <> BIG_BOSS AND nouveau.salaire > ancien.salaire * 1.2 (ERROR 31/32 11