Bonsoir ced, bonsoir capitaine,
Passons au niveau SQL. Pour déclarer les tables COMPAGNIE et PILOTE, pas de problème :
CREATE TABLE COMPAGNIE
(
id_cie INT NOT NULL
, nom_cie VARCHAR(32) NOT NULL
, CONSTRAINT COMPAGNIE_PK PRIMARY KEY (id_cie)
) ;
CREATE TABLE PILOTE
(
id_pilote INT NOT NULL
, nom_pilote VARCHAR(32) NOT NULL
, prenom_pilote VARCHAR(32) NOT NULL
, CONSTRAINT PILOTE_PK PRIMARY KEY (id_pilote)
) ;
A partir de là, je propose une solution alternative, permettant d’éviter de mettre en œuvre des triggers et autres lourdeurs pour s’assurer qu’un filleul et son parrain font partie de la même compagnie.
Tout d’abord, comme un pilote peut n’appartenir à aucune compagnie, afin d’éviter l’intrusion du bonhomme NULL, pour l’association entre COMPAGNIE et PILOTE, je mets en oeuvre une table de clé primaire {id_pilote}, avec des NOT NULL partout :
CREATE TABLE PILOTE_CIE
(
id_cie INT NOT NULL
, id_pilote INT NOT NULL
, date_embauche DATE NOT NULL
, CONSTRAINT PILOTE_CIE_PK PRIMARY KEY (id_pilote)
, CONSTRAINT PILOTE_CIE_AK UNIQUE (id_cie, id_pilote)
, CONSTRAINT PILOTE_CIE_PILOTE_FK FOREIGN KEY (id_pilote)
REFERENCES PILOTE (id_pilote)
, CONSTRAINT PILOTE_CIE_COMPAGNIE_FK FOREIGN KEY (id_cie)
REFERENCES COMPAGNIE (id_cie)
) ;
Observez la présence d’une surclé {id_cie, id_pilote}, c’est grâce à elle qu’on sous-traitera au SGBD le contrôle de la contrainte.
Concernant le parrainage : pour éviter là encore l’intrusion de NULL, je mets en œuvre une table à cet effet, en relation non pas avec PILOTE mais avec PILOTE_CIE, afin que l’attribut id_cie fasse partie de l’en-tête de la table :
CREATE TABLE PARRAINAGE
(
id_cie INT NOT NULL
, id_pilote INT NOT NULL
, id_parrain INT NOT NULL
, date_parrainage DATE NOT NULL
, CONSTRAINT PARRAINAGE_PK PRIMARY KEY (id_pilote)
, CONSTRAINT PARRAINAGE_FILLEUL_FK FOREIGN KEY (id_cie, id_pilote)
REFERENCES PILOTE_CIE (id_cie, id_pilote)
, CONSTRAINT PARRAINAGE_PARRAIN_FK FOREIGN KEY (id_cie, id_parrain)
REFERENCES PILOTE_CIE (id_cie, id_pilote)
, CONSTRAINT PARRAINAGE_CK1 CHECK (id_pilote <> id_parrain)
) ;
Observez que les clés étrangères font référence (c’est légal) non pas à la clé primaire de PILOTE_CIE, mais à la surclé.
Un début de jeu d’essai conforme :
INSERT INTO COMPAGNIE (id_cie, nom_cie) VALUES (1, 'Air Dugoineau') ;
INSERT INTO COMPAGNIE (id_cie, nom_cie) VALUES (2, 'Air Mado') ;
INSERT INTO PILOTE (id_pilote, nom_pilote, prenom_pilote) VALUES (1, 'Naudin', 'Fernand') ;
INSERT INTO PILOTE (id_pilote, nom_pilote, prenom_pilote) VALUES (2, 'Volfoni', 'Raoul') ;
INSERT INTO PILOTE (id_pilote, nom_pilote, prenom_pilote) VALUES (3, 'Volfoni', 'Paul') ;
INSERT INTO PILOTE (id_pilote, nom_pilote, prenom_pilote) VALUES (4, 'Delafoix', 'Antoine') ;
INSERT INTO PILOTE (id_pilote, nom_pilote, prenom_pilote) VALUES (5, 'Haddock', 'Archibald') ;
INSERT INTO PILOTE_CIE (id_cie, id_pilote, date_embauche) VALUES (1, 1, '1960-01-01') ;
INSERT INTO PILOTE_CIE (id_cie, id_pilote, date_embauche) VALUES (1, 2, '1961-02-01') ;
INSERT INTO PILOTE_CIE (id_cie, id_pilote, date_embauche) VALUES (2, 3, '1962-02-01') ;
INSERT INTO PILOTE_CIE (id_cie, id_pilote, date_embauche) VALUES (1, 4, '1961-02-01') ;
INSERT INTO PARRAINAGE (id_cie, id_pilote, id_parrain, date_parrainage) VALUES (1, 2, 1, '1970-01-01') ;
INSERT INTO PARRAINAGE (id_cie, id_pilote, id_parrain, date_parrainage) VALUES (1, 4, 1, '1970-01-01') ;
Essayons de faire parrainer un pilote par un parrain d’une autre compagnie :
INSERT INTO PARRAINAGE (id_cie, id_pilote, id_parrain, date parrainage) VALUES (1, 3, 1, '1970-01-01') ;
Il est évident que le SGBD rejette l'insert. Le pilote 3 fait bien partie de la compagnie 1, mais son parrain 1 fait partie de la compagnie 2, or il n’y a qu’une seule valeur possible pour la compagnie (attribut id_cie) d’un pilote et celle de son parrain...
L’objet de la surclé de la table PILOTE_CIE était de permettre de propager l’attribut id_cie jusqu’à l’en-tête de la table PARRAINAGE, ce qui permet de garantir qu’un pilote et son parrain font bien partie de la même compagnie. □⃞⃞
Partager