Maîtrise d`Informatique
Transcription
Maîtrise d`Informatique
SEANCE 5 : CONTRAINTES D'INTEGRITE ET TRIGGERS SQL Exercice 1. Contraintes d’intégrité référentielle. Drop TABLE DET; Drop TABLE PRO; Drop TABLE COM; Drop TABLE FOU; Drop TABLE CLI; CREATE TABLE CLI( NumCli number(5) Constraint PK_Cli PRIMARY KEY, NomCli char(20) NOT NULL, Pays char(30), Tel char(15), Ville char(15), Dept char(30), Nat char(15)); CREATE TABLE FOU( NumFou number(2) Constraint PK_FOU PRIMARY KEY, NomFou char(20) NOT NULL, Pays char(30), Tel char(15)); CREATE TABLE COM( NumCom number(5) Constraint PK_COM PRIMARY KEY, NumCli Number(5) Constraint COM_REF_CLI REFERENCES Cli, FraisPort number(4), AnCom number(4), DateCom date, Payement number); CREATE TABLE PRO( NumPro number(5) Constraint PK_PRO PRIMARY KEY, NumFou number(2) Constraint PRO_REF_FOU REFERENCES Fou, NomPro char(20), TypePro char(10), PrixUnit number(3)); CREATE TABLE DET( NumCom number(5) Constraint DET_REF_COM REFERENCES Com, NumPro number(5) Constraint DET_REF_PRO REFERENCES Pro, Qte number(5), Remise number(5), Constraint PK_DET PRIMARY KEY (NumCom, NumPro)); --- TEST : PROMPT insertion du client 101: insert into CLI values (101,'test','test','test','test','test','test'); PROMPT insertion du client 102 et de sa commande: insert into CLI values (102,'test','test','test','test','test','test'); insert into COM values (99000,102,26,1999,TO_DATE('28-11-2001', 'DD-MM-YYYY'),0); PROMPT suppression du client 101: delete from cli where cli.numcli = 101; PROMPT : la suppression se passe bien puisque le client 101 n'a pas commandé => 1 row deleted PROMPT suppression du client 102: delete from cli where cli.numcli = 102; PROMPT puisque le client 102 a fait une commande, le système doit renvoyer qu'une contrainte d'intégrité est levée et empecher le delete. -- nettoyage : delete from COM where Numcom=99000; delete from CLI where Numcli=101; delete from CLI where Numcli=102; Exercice 2. Contraintes de non-nullité. ALTER TABLE Cli MODIFY NomCli NOT NULL; ALTER TABLE Fou MODIFY NomFou NOT NULL; PROMPT insertion du client 110 avec NomCli!=NULL: insert into CLI values (110,'test','test','test','test','test','test'); PROMPT insertion du client 111 avec NomCli=NULL: insert into CLI values (111, NULL,'test','test','test','test','test'); insert into CLI (numcli, pays, tel, ville, dept, nat) values (112, 'test','test','test','test','test'); PROMPT l'insertion doit etre rejetée au motif que la contrainte de non nullité de l'attribut NomCli est levée PROMPT insertion du fournisseur 40 avec NomFou!=NULL: insert into FOU values (40,'Forjts','Norvege','2440898090'); PROMPT insertion du fournisseur 41 avec NomFou=NULL: insert into FOU values (41,NULL,'Norvege','2440898090'); insert into FOU (numfou, pays, tel) values (41,'Norvege','2440898090'); PROMPT l'insertion doit etre rejetée au motif que la contrainte de non nullité de l'attribut NomFou est levée -- nettoyage : delete from CLI where Numcli=110; delete from CLI where Numcli=111; delete from CLI where Numcli=112; delete from FOU where NumFou=40; delete from FOU where NumFou=41; delete from FOU where NumFou=42; Exercice 3. Domaine de variation et dépendance DELETE FROM Com ; DELETE FROM Cli ; ALTER TABLE Cli MODIFY Nat Char(2); ALTER TABLE Cli DROP CONSTRAINT domaine_pays; ALTER TABLE Cli ADD ( CONSTRAINT domaine_pays CHECK (Nat IN ('GB', 'D', 'E', 'B') OR (Nat ='FR' AND Dept IS NOT NULL)) ); --- TEST : 1 PROMPT insertion d'un client tel que CLI.dept!=NULL et CLI.nat=xx insert into Cli values(140,'nom','pays','tel','ville', 'dept', 'xx'); PROMPT levée de la contrainte : l'insertion de ce client doit échouer car Nat n'est pas dans {FR,GB,D,E,B} PROMPT iunsertion d'un client tel que CLI.dept=NULL et CLI.nat=GB insert into Cli values(141,'nom','pays','tel','ville', NULL, 'GB'); PROMPT pas de levée de la contrainte : l'insertion passe PROMPT iunsertion d'un client tel que CLI.dept=NULL et CLI.nat=FR insert into Cli values(142,'nom','pays','tel','ville', NULL, 'FR'); PROMPT levée de la contrainte : l'insertion ne passe pas car la nationnalité est FR et dept est NULL Exercice 4. Dépendance fonctionnelle CREATE OR REPLACE TRIGGER Ville_Dept AFTER UPDATE OR INSERT ON Cli DECLARE nb NUMBER ; BEGIN SELECT MAX(T.nb_dept) into nb FROM (SELECT COUNT(DISTINCT dept) nb_dept FROM Cli GROUP BY Ville) T ; IF (nb > 1) THEN RAISE_APPLICATION_ERROR(-20001,'Depts differents pour une même ville'); END IF ; END ; / ----------- TEST ----------prompt delete from cli; delete from cli; prompt insert into Cli values(1,'nom','pays','tel','paris','idf','FR'); insert into Cli values(1,'nom','pays','tel','paris','idf','FR'); prompt insert into Cli values(2,'nom','pays','tel','paris','paca','FR'); insert into Cli values(2,'nom','pays','tel','paris','paca','FR'); -- Levée de la contrainte Exercice 5. Contraintes d’intégrité référentielle – on update cascade CREATE OR REPLACE TRIGGER maj_client_cascade AFTER UPDATE ON Cli FOR EACH ROW BEGIN UPDATE COM SET numcli = :new.NumCli WHERE numcli = :old.Numcli ; END ; / -- TEST : -- delete from com; delete from cli; insert into cli values(1,'nom','pays','tel','ville','dept','nat'); insert into cli values(2,'nom','pays','tel','ville','dept','nat'); insert into com values(1,1,1,1,TO_DATE('30-11-2001', 'DD-MM-YYYY'), 10); insert into com values(2,2,1,1,TO_DATE('30-11-2001', 'DD-MM-YYYY'), 10); PROMPT ---- BEFORE UPDATE ---select * from cli; select * from com; PROMPT ---- update cli set numcli=3 where numcli=2; ---update cli set numcli=3 where numcli=1; PROMPT ---- AFTER UPDATE ---select * from cli; select * from com; drop trigger maj_client_cascade; Exercice 6. Contrainte temporelle DROP SEQUENCE order_com; CREATE SEQUENCE order_com; CREATE OR REPLACE TRIGGER maj_auto_order BEFORE INSERT OR UPDATE ON com FOR EACH ROW BEGIN SELECT order_com.nextval into :new.orderCom FROM dual; END ; / CREATE OR REPLACE TRIGGER check_com_order AFTER INSERT OR UPDATE ON com DECLARE nb NUMBER := 0; BEGIN SELECT count(*) into nb FROM com c1, com c2 WHERE c1.orderCom < c2.orderCom and c1.datecom > c2.datecom ; IF (nb >= 1) THEN RAISE_APPLICATION_ERROR(-20006,'impossible d antidater une commande'); END IF ; END ; / -- TEST : -delete from com; delete from cli; insert into cli values(1,'nom','pays','tel','ville','dept','nat'); insert into cli values(2,'nom','pays','tel','ville','dept','nat'); insert into com values(1,null,1,1,1,TO_DATE('29-11-2001', 'DD-MM-YYYY'), 10); commit; insert into com values(2,null,2,1,1,TO_DATE('30-11-2001', 'DD-MM-YYYY'), 10); commit; 2 insert into com values(3,null,2,1,1,TO_DATE('28-11-2001', 'DD-MM-YYYY'), 10); commit; insert into com values(4,null,1,1,1,TO_DATE('29-12-2001', 'DD-MM-YYYY'), 10); insert into com values(5,null,2,1,1,TO_DATE('28-12-2001', 'DD-MM-YYYY'), 10); PROMPT ---- BEFORE UPDATE ---select * from cli; select * from com; drop trigger maj_auto_order; drop trigger check_com_order; 3