Exercice (6 points) — dans l'esprit des sessions 2016–2025, section Sciences de l'informatique
La coopérative Zitouna Plus de Sfax suit les livraisons d'olives de ses adhérents aux huileries de la région à l'aide de la base de données Gestion_Huileries, dont la représentation textuelle est la suivante (clés primaires soulignées, clés étrangères suivies de #) :
- Huilerie ( codeHui , nomHui , ville , capaciteJour )
- Agriculteur ( cinAgr , nomAgr , telAgr )
- Variete ( codeVar , libVar )
- Livraison ( numLiv , dateLiv , poidsKg , etat , codeVar# , cinAgr# , codeHui# )
| Champ | Description |
|---|---|
| capaciteJour | Quantité d'olives, en kg, qu'une huilerie peut triturer en une journée. |
| cinAgr | Numéro de la carte d'identité d'un agriculteur, 8 chiffres. |
| telAgr | Téléphone d'un agriculteur, 8 chiffres. |
| poidsKg | Poids d'olives livré, en kg. |
| etat | État d'une livraison : « A » (en attente de trituration) ou « T » (triturée). |
Les tables ont été créées par les requêtes suivantes :
CREATE TABLE Huilerie (
codeHui CHAR(4) PRIMARY KEY,
nomHui VARCHAR(30) NOT NULL UNIQUE,
ville VARCHAR(20) NOT NULL,
capaciteJour INT CHECK (capaciteJour > 0)
);
CREATE TABLE Agriculteur (
cinAgr CHAR(8) PRIMARY KEY,
nomAgr VARCHAR(40) NOT NULL,
telAgr CHAR(8) UNIQUE
);
CREATE TABLE Variete (
codeVar CHAR(3) PRIMARY KEY,
libVar VARCHAR(20) NOT NULL
);
CREATE TABLE Livraison (
numLiv INT PRIMARY KEY,
dateLiv DATE NOT NULL,
poidsKg INT NOT NULL
CHECK (poidsKg BETWEEN 50 AND 5000),
etat CHAR(1) DEFAULT 'A'
CHECK (etat IN ('A', 'T')),
codeVar CHAR(3),
cinAgr CHAR(8),
codeHui CHAR(4),
FOREIGN KEY (codeVar)
REFERENCES Variete (codeVar),
FOREIGN KEY (cinAgr)
REFERENCES Agriculteur (cinAgr),
FOREIGN KEY (codeHui)
REFERENCES Huilerie (codeHui)
ON DELETE CASCADE
);On donne le contenu actuel des tables ; chaque question part de ce contenu.
Table Huilerie
| codeHui | nomHui | ville | capaciteJour |
|---|---|---|---|
| H001 | Huilerie El Amal | Sfax | 40000 |
| H002 | Zitouna Sahel | Mahdia | 25000 |
| H003 | Huilerie Nour | Sfax | 18000 |
Table Agriculteur
| cinAgr | nomAgr | telAgr |
|---|---|---|
| 04512378 | Ben Salem Moncef | 98456123 |
| 07789012 | Trabelsi Najet | 22314567 |
| 09876543 | Gharbi Hedi |
Table Variete
| codeVar | libVar |
|---|---|
| CHM | Chemlali |
| CHT | Chétoui |
| OUS | Oueslati |
Table Livraison
| numLiv | dateLiv | poidsKg | etat | codeVar | cinAgr | codeHui |
|---|---|---|---|---|---|---|
| 301 | 2025-11-18 | 1200 | T | CHM | 04512378 | H001 |
| 302 | 2025-11-18 | 800 | T | CHT | 07789012 | H002 |
| 303 | 2025-11-20 | 2500 | A | CHM | 09876543 | H001 |
| 304 | 2025-11-21 | 650 | A | OUS | 04512378 | H003 |
Requêtes de la question 1 :
-- a)
INSERT INTO Agriculteur
VALUES ('07789012', 'Jlassi Rim', '55667788');
-- b)
UPDATE Livraison SET codeVar = 'ARB'
WHERE numLiv = 304;
-- c)
DELETE FROM Agriculteur
WHERE cinAgr = '04512378';
-- d)
INSERT INTO Livraison (numLiv, dateLiv,
poidsKg, codeVar, cinAgr, codeHui)
VALUES (305, '2025-11-22', 7200, 'CHT',
'07789012', 'H002');Document 1 — lignes à insérer, dans l'ordre, d'abord dans la table Agriculteur puis dans la table Livraison (toutes les variétés et toutes les huileries citées existent déjà) :
| N° ligne | cinAgr | nomAgr | telAgr |
|---|---|---|---|
| 1 | 11223344 | Mansouri Fathi | 97111222 |
| 2 | 12345678 | Ayari Samia | 50123456 |
| 3 | 13572468 | Hammami Lotfi | 21987654 |
| 4 | 12345678 | Dridi Kamel | 93456789 |
| N° ligne | numLiv | dateLiv | poidsKg | etat | codeVar | cinAgr | codeHui |
|---|---|---|---|---|---|---|---|
| 1 | 305 | 2025-11-24 | 900 | A | CHM | 11223344 | H002 |
| 2 | 306 | 2025-11-24 | 1500 | A | CHT | 1357246 | H001 |
| 3 | 307 | 2025-11-25 | 30 | A | OUS | 12345678 | H003 |
| 4 | 308 | 2025-11-25 | 2200 | T | CHM | 13572468 | H003 |
| 5 | 304 | 2025-11-26 | 700 | A | CHT | 11223344 | H001 |
| 6 | 309 | 2025-11-26 | 1100 | X | CHM | 12345678 | H002 |
Propositions de la question 3 :
- a. La suppression de l'huilerie « H003 » entraîne la suppression automatique de la livraison 304.
- b. Il est possible d'enregistrer deux huileries portant le même nom.
- c. Une livraison enregistrée sans préciser son état prend l'état « A ».
- d. Il est possible d'enregistrer un agriculteur sans numéro de téléphone.
- e. Il est possible d'enregistrer une huilerie dont la capacité journalière vaut 0 kg.
- f. La suppression de la variété « OUS » entraîne la suppression automatique de la livraison 304.
Besoins de la question 4 — la coopérative se propose de créer la table Ouvrier ( matOuv , nomOuv , numCnss , salaireJour , codeHui# ) :
- a. Attribuer au salaire journalier la valeur 30 dinars lorsqu'aucune valeur ne lui est affectée : ☐ CHECK ☐ DEFAULT ☐ NULL
- b. Interdire que deux ouvriers aient le même numéro de CNSS : ☐ REFERENCES ☐ DISTINCT ☐ UNIQUE
- c. Relier chaque ouvrier à l'huilerie où il travaille : ☐ REFERENCES ☐ UNIQUE ☐ NOT NULL
- d. Ajouter plus tard, à la table déjà créée, une contrainte nommée « ckSal » interdisant un salaire nul ou négatif : ☐ UPDATE ☐ CREATE TABLE ☐ ALTER TABLE
- L'exécution de chacune des requêtes a), b), c) et d) génère une erreur. Indiquer pour chaque requête la contrainte d'intégrité non respectée et justifier la réponse.
- Lors de l'insertion des lignes du document 1, le SGBD génère des erreurs au niveau de quelques lignes. Pour chaque erreur, indiquer le numéro de la ligne, le nom de la table, le nom du champ ainsi que la contrainte d'intégrité non respectée (intégrité de table (clé primaire), intégrité référentielle ou intégrité de domaine).
- Pour chacune des propositions a) à f), répondre par V si elle est correcte ou par F dans le cas contraire, et justifier la réponse par la clause de la contrainte correspondante utilisée dans les requêtes de création.
- Pour chacun des besoins a) à d), mettre une croix devant le mot-clé SQL qui convient.
Voir la correction commentéeAprès avoir posé votre démarche
1. Idée : comparer la valeur en cause au contenu des tables : clé déjà présente → intégrité de table ; valeur de clé étrangère absente de la table mère, ou ligne mère encore référencée → intégrité référentielle ; valeur interdite par CHECK ou champ NOT NULL vide → intégrité de domaine.
- 1.a Intégrité de table (clé primaire) : le CIN « 07789012 » est déjà celui de Trabelsi Najet ; cinAgr est la clé primaire d'Agriculteur et ne peut pas se répéter.
- 1.b Intégrité référentielle : la variété « ARB » n'existe pas dans la table mère Variete ; la clé étrangère codeVar de la livraison 304 référencerait une ligne inexistante.
- 1.c Intégrité référentielle : les livraisons 301 et 304 référencent cet agriculteur. La clé étrangère cinAgr est déclarée sans ON DELETE CASCADE : la suppression laisserait deux livraisons orphelines, le SGBD la refuse.
- 1.d Intégrité de domaine : 7200 kg sort de l'intervalle imposé par
CHECK (poidsKg BETWEEN 50 AND 5000).
2. Idée : insérer les lignes dans l'ordre en tenant à jour le contenu des tables : une ligne acceptée devient une ligne mère possible pour les suivantes, une ligne refusée n'est pas enregistrée.
| Ligne | Table | Champ | Contrainte non respectée |
|---|---|---|---|
| 4 | Agriculteur | cinAgr | Intégrité de table (clé primaire) : « 12345678 » vient d'être inséré à la ligne 2 |
| 2 | Livraison | cinAgr | Intégrité référentielle : « 1357246 » (7 chiffres) n'existe pas dans Agriculteur |
| 3 | Livraison | poidsKg | Intégrité de domaine : 30 kg est inférieur au minimum de 50 kg |
| 5 | Livraison | numLiv | Intégrité de table (clé primaire) : la livraison 304 existe déjà |
| 6 | Livraison | etat | Intégrité de domaine : « X » n'est ni « A » ni « T » |
La ligne 3 de Livraison ne viole aucune contrainte référentielle : l'agriculteur « 12345678 » existe (Ayari Samia, ligne 2 d'Agriculteur) ; seul le poids est en cause. Les lignes 1 et 4 de Livraison et les lignes 1 à 3 d'Agriculteur sont enregistrées.
3. Idée : chaque réponse se justifie par la clause précise de la requête CREATE TABLE qui autorise ou interdit l'opération.
| Proposition | Réponse | Clause justificative |
|---|---|---|
| a | V | ON DELETE CASCADE sur la clé étrangère codeHui de Livraison |
| b | F | nomHui VARCHAR(30) NOT NULL UNIQUE |
| c | V | etat CHAR(1) DEFAULT 'A' |
| d | V | telAgr CHAR(8) UNIQUE, sans NOT NULL : la saisie n'est pas obligatoire (Gharbi Hedi n'a pas de téléphone) |
| e | F | CHECK (capaciteJour > 0) : 0 n'est pas strictement positif |
| f | F | FOREIGN KEY (codeVar) REFERENCES Variete (codeVar), sans ON DELETE CASCADE : « OUS » est encore référencée par la livraison 304, sa suppression est refusée |
4. Idée : DEFAULT remplit à la place de l'utilisateur, UNIQUE interdit un doublon sur une colonne qui n'est pas la clé, REFERENCES crée le lien avec la table mère ; une contrainte ajoutée à une table existante passe par ALTER TABLE.
a. DEFAULT ; b. UNIQUE ; c. REFERENCES ; d. ALTER TABLE. Par exemple :
CREATE TABLE Ouvrier (
matOuv INT PRIMARY KEY,
nomOuv VARCHAR(40) NOT NULL,
numCnss CHAR(10) UNIQUE,
salaireJour DECIMAL(6,3) DEFAULT 30,
codeHui CHAR(4),
FOREIGN KEY (codeHui)
REFERENCES Huilerie (codeHui)
);
ALTER TABLE Ouvrier
ADD CONSTRAINT ckSal
CHECK (salaireJour > 0);