Aller au contenu

Un mot pour Fahmio

Tu écris. Tu continues.

Un problème, une idée — assez pour qu’on comprenne, puis tu retournes à ta copie.

On lit. Tu n’as rien d’autre à faire.

Où veux-tu aller ?

↑ ↓ pour parcourir · Entrée pour ouvrir · Échap pour fermer

Fahmio
Fahmio
Bac Tunisie
BD-GBases de données et SQL

Mises à jour racontées : INSERT dans l'ordre des clés étrangères, valeur inconnue (NULL), UPDATE en pourcentage via une sous-requête, suppression sans cascade, insertion refusée

Idée directrice

Le sujet raconte un événement de gestion avec toutes ses valeurs — une station inaugurée, un trajet en cours, une remise, une purge d'anciennes données — et demande les requêtes INSERT, UPDATE ou DELETE qui le traduisent. Deux réflexes décident de la note : l'ordre imposé par les clés étrangères (insérer les tables mères avant les filles, supprimer les filles avant la mère quand aucune clause ON DELETE CASCADE n'est déclarée) et la précision du WHERE (une mise à jour sans condition touche toute la table). Le sujet fait aussi expliquer pourquoi une insertion est refusée : clé primaire dupliquée, ligne mère absente, valeur trop longue.

Ce qui aide à reconnaître la démarche

« Écrire les requêtes SQL permettant d'insérer les données relatives à … dans les différentes tables » ; « supprimer de la base toutes les données relatives aux … » ; « augmenter de 5% tous les … » ; « Comment réduire de 15 % les prix » ; « quelles sont les tables qui seront touchées ? » ; « une nouvelle intervention non achevée »

Besoin d’un point de départ ? Voir la méthode
  • Repérer les clés étrangères de chaque table touchée : INSERT des mères vers les filles, DELETE des filles vers la mère (sauf si ON DELETE CASCADE est déclaré).
  • Valeur inconnue, auto-incrémentée ou par défaut : INSERT INTO T (colonnes renseignées) VALUES (…) ; les colonnes omises prennent NULL, leur valeur par défaut ou le numéro suivant.
  • Pourcentage : SET col = col * 0.85 pour −15 %, * 1.05 pour +5 % ; critère situé dans une autre table : WHERE cle IN (SELECT … jointure …).
  • Toujours écrire et relire le WHERE d'un UPDATE ou d'un DELETE : sans lui, toute la table est modifiée.
  • Insertion refusée : clé primaire déjà présente, ligne mère absente, valeur trop longue ou hors domaine (CHECK), champ obligatoire laissé vide.
Les pièges à vérifier dans ta démarche

Insérer le vélo avant sa station ou son modèle ; supprimer les vélos avant leurs trajets et leurs réparations ; écrire SET montant = 0.85 (tous les montants valent alors 0,850) au lieu de montant = montant * 0.85 ; ne tester que MONTH en oubliant l'année ; borner par BETWEEN une colonne date-heure avec une date seule (le dernier jour est perdu) ; fournir quatre valeurs pour une table de six colonnes sans nommer les colonnes.

Sujet principal

Exercice (5 points) — dans l'esprit des sessions 2015–2025, section Sciences de l'informatique

12 questionsCorrigé masqué

La base VéloCité du service municipal de vélos en libre-service de Sfax a la représentation textuelle suivante (clés primaires soulignées, clés étrangères suivies de #) :

  • Station ( idStation , nomStation , quartier , capacite )
  • Modele ( codeModele , libModele , typeModele , tarifMinute )
  • Velo ( idVelo , dateService , codeModele# , idStation# )
  • Formule ( codeFormule , libFormule , prixMensuel )
  • Abonne ( numAbonne , nomAbonne , telAbonne , emailAbonne , codeFormule# )
  • Trajet ( idTrajet , dateTrajet , dureeMin , montant , idVelo# , numAbonne# )
  • Reparation ( idVelo# , dateRep , panne , cout )
ChampDescription
idStationIdentifiant d'une station, entier.
nomStationNom d'une station, chaîne de 20 caractères.
quartierQuartier où se trouve une station, chaîne de 30 caractères.
capaciteNombre maximal de vélos d'une station, entier.
codeModeleCode d'un modèle de vélo, chaîne de 4 caractères.
libModeleLibellé d'un modèle, chaîne de 30 caractères.
typeModeleType d'un modèle, « Classique » ou « Electrique », chaîne de 10 caractères.
tarifMinutePrix d'une minute de trajet, en dinars, réel.
idVeloIdentifiant d'un vélo, entier.
dateServiceDate de mise en service d'un vélo.
codeFormuleCode d'une formule d'abonnement, chaîne de 3 caractères.
libFormuleLibellé d'une formule (Journalier, Mensuel, Annuel…), chaîne de 20 caractères.
prixMensuelPrix mensuel d'une formule, en dinars, réel.
numAbonneNuméro d'un abonné, entier.
nomAbonneNom et prénom d'un abonné, chaîne de 40 caractères.
telAbonneTéléphone d'un abonné, chaîne de 8 caractères.
emailAbonneAdresse mail d'un abonné, chaîne de 50 caractères.
idTrajetIdentifiant d'un trajet, entier.
dateTrajetDate d'un trajet (sans heure).
dureeMinDurée d'un trajet, en minutes, entier.
montantMontant payé pour un trajet, en dinars, réel.
dateRepDate d'une réparation.
panneDescription de la panne réparée, chaîne de 50 caractères.
coutCoût d'une réparation, en dinars, réel.

Les clés étrangères ont été déclarées sans l'option ON DELETE CASCADE. Seuls les champs emailAbonne, dureeMin et montant peuvent rester vides ; tous les autres sont obligatoires. On donne l'extrait suivant de la table Formule :

codeFormulelibFormuleprixMensuel
F1Journalier3.000
F2Mensuel15.000
F3Annuel150.000

Écrire les requêtes SQL permettant de répondre aux situations suivantes :

  1. Le 12 avril 2026, la municipalité inaugure la station d'identifiant 14, nommée « Port de pêche », située dans le quartier « Sidi Mansour », d'une capacité de 20 vélos. Le même jour, elle reçoit un nouveau modèle de code « M7 », de libellé « VéloCargo », de type « Electrique », au tarif de 0,120 dinar la minute ; le vélo d'identifiant 305, de ce modèle, est mis en service et stationné dans la nouvelle station. Écrire, dans un ordre d'exécution correct, les requêtes permettant d'enregistrer ces informations.
  2. Le 13 avril 2026, l'abonné numéro 1024, déjà enregistré, emprunte le vélo 305 ; le trajet reçoit l'identifiant 90871. Le vélo n'étant pas encore restitué, la durée et le montant du trajet ne sont pas connus. Écrire la requête permettant d'enregistrer ce trajet.
  3. Une erreur du système de paiement a surfacturé les trajets effectués en mars 2026 avec un vélo de type « Electrique ». On se propose de réduire de 15 % le montant de ces trajets.
  4. Pour renouveler le parc, on se propose de supprimer de la base toutes les données relatives aux vélos mis en service avant le 1er janvier 2019. Écrire l'ensemble des requêtes correspondantes.
  5. Pour chacune des requêtes a), b), c) et d) ci-dessous, dire si elle sera exécutée ou refusée par le SGBD ; en cas de refus, préciser la contrainte non respectée.
-- a)
INSERT INTO Formule
VALUES ('F2', 'Etudiant', 12.000);
-- b)
INSERT INTO Abonne
VALUES (2051, 'Sami Ben Salah', '98123456',
        'sami.bs@mail.tn', 'F9');
-- c)
INSERT INTO Station
VALUES (15, 'Cité El Habib Entrée Nord',
        'El Habib', 25);
-- d)
INSERT INTO Abonne (numAbonne, nomAbonne,
                    telAbonne, codeFormule)
VALUES (2052, 'Rim Trabelsi', '55001122', 'F3');
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : Velo référence Station (idStation#) et Modele (codeModele#) : ces deux lignes mères doivent exister avant l'insertion du vélo ; leur ordre entre elles est libre.

INSERT INTO Station
VALUES (14, 'Port de pêche', 'Sidi Mansour', 20);
INSERT INTO Modele
VALUES ('M7', 'VéloCargo', 'Electrique', 0.120);
INSERT INTO Velo
VALUES (305, '2026-04-12', 'M7', 14);

Exécutée en premier, l'insertion du vélo serait refusée : la station 14 et le modèle M7 n'existent pas encore (intégrité référentielle).

2. Idée : deux valeurs manquent : on nomme les colonnes renseignées, les autres (dureeMin, montant) prennent la valeur NULL, ce que la description autorise.

INSERT INTO Trajet (idTrajet, dateTrajet,
                    idVelo, numAbonne)
VALUES (90871, '2026-04-13', 305, 1024);

Équivalent : INSERT INTO Trajet VALUES (90871, '2026-04-13', NULL, NULL, 305, 1024);. Sans liste de colonnes et avec quatre valeurs seulement, la requête serait refusée : la table a six colonnes.

3. Idée : le critère « type Electrique » est dans Modele, pas dans Trajet : une sous-requête sélectionne les vélos concernés, YEAR et MONTH fixent la période ; réduire de 15 % revient à multiplier par 0,85.

UPDATE Trajet
SET montant = montant * 0.85
WHERE YEAR(dateTrajet) = 2026
  AND MONTH(dateTrajet) = 3
  AND idVelo IN (
      SELECT idVelo FROM Velo V, Modele M
      WHERE V.codeModele = M.codeModele
        AND typeModele = 'Electrique');

Par exemple, un trajet de mars 2026 facturé 4,800 D sur un vélo électrique passe à 4,800×0,85=4,080 D4{,}800 \times 0{,}85 = \boxed{4{,}080\text{ D}} ; un trajet de mars sur un vélo classique, ou d'avril sur un vélo électrique, ne change pas.

4. Idée : sans ON DELETE CASCADE, supprimer un vélo encore référencé est refusé : on supprime d'abord les lignes filles (Reparation et Trajet, dans un ordre quelconque), puis les vélos.

DELETE FROM Reparation
WHERE idVelo IN (SELECT idVelo FROM Velo
                 WHERE dateService < '2019-01-01');
DELETE FROM Trajet
WHERE idVelo IN (SELECT idVelo FROM Velo
                 WHERE dateService < '2019-01-01');
DELETE FROM Velo
WHERE dateService < '2019-01-01';

5. Idée : pour chaque insertion, vérifier la clé primaire (valeur déjà présente ?), les clés étrangères (la ligne mère existe-t-elle ?), la taille et le caractère obligatoire des valeurs.

  • a) Refusée : le code « F2 » existe déjà dans Formule (formule Mensuel) ; la contrainte de clé primaire interdit un doublon.
  • b) Refusée : aucune formule « F9 » n'existe ; la clé étrangère codeFormule viole l'intégrité référentielle.
  • c) Refusée : « Cité El Habib Entrée Nord » compte 25 caractères alors que nomStation en admet 20 au maximum (valeur trop longue pour le domaine du champ ; refus en mode strict, mode par défaut de MySQL).
  • d) Exécutée : la liste de colonnes omet emailAbonne, qui peut rester vide et prend la valeur NULL ; la formule F3 existe.

Changer d’énoncé, garder le raisonnement

Choisis un seul transfert après le sujet principal. Qu’est-ce qui change ? Quel résultat ou quelle méthode peux-tu réutiliser ? Les autres exercices restent disponibles pour une prochaine séance.

Variantes rencontrées : insertion d'un client puis de sa location, mères d'abord (principale 2015), d'un séjour dans trois tables encore vides (contrôle 2021) ; augmentation de 5 % des loyers antérieurs à une date (principale 2015), réduction de 20 % sur un libellé LIKE (contrôle 2019), de 15 % pour une manifestation (principale 2025) ; suppression en cascade manuelle des télévisions vendues avant 2010 (contrôle 2020) ; tables touchées par la suppression d'un client avec ON DELETE CASCADE (principale 2015) ; identifiant auto-incrémenté omis (contrôle 2024) ; intervention non achevée insérée sans date de fin (contrôle 2025) ; diminution de 2 unités des mesures d'une période (principale 2024) ; origine d'une erreur d'insertion liée à la taille (contrôle 2015).

Exercices d'entraînement — une nuance à la fois

1 Drill BD-G.1 — identifiant auto-incrémenté et valeur par défaut : nommer les colonnes
Entraînement 01 / 05

Drill BD-G.1 — identifiant auto-incrémenté et valeur par défaut : nommer les colonnes

4 questionsCorrigé masqué

Une société de télécommunication enregistre les réclamations de ses clients. La table Reclamation a été créée par la requête suivante ; la table Client existe et contient le client de CIN « 07123456 ».

CREATE TABLE Reclamation (
  numRec INT PRIMARY KEY AUTO_INCREMENT,
  dateRec DATE NOT NULL,
  objet VARCHAR(40) NOT NULL,
  etat CHAR(1) DEFAULT 'O',
  cinClient CHAR(8) NOT NULL
    REFERENCES Client (cinClient)
);

Le dernier numéro de réclamation attribué est 57.

  1. Écrire la requête qui enregistre la réclamation du 2 mai 2026, d'objet « Facture erronée », à l'état « O » (ouverte), du client « 07123456 ».
  2. Quel numéro cette réclamation reçoit-elle ?
  3. La requête R ci-dessous est refusée. Pourquoi ?
  4. Écrire la requête qui enregistre la réclamation du 4 mai 2026, d'objet « Coupure de ligne », du même client, sans préciser son état. Quel état prend-elle ?

Requête R :

INSERT INTO Reclamation
VALUES ('2026-05-02', 'Facture erronée',
        'O', '07123456');
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : numRec est attribué par le SGBD : on ne le fournit pas, donc on nomme les colonnes renseignées.

INSERT INTO Reclamation (dateRec, objet,
                         etat, cinClient)
VALUES ('2026-05-02', 'Facture erronée',
        'O', '07123456');

2. Le compteur auto-incrémenté donne le numéro suivant le dernier attribué : 58\boxed{58}.

3. Sans liste de colonnes, VALUES doit fournir une valeur pour chacune des cinq colonnes, dans l'ordre de la table ; R n'en donne que quatre, la requête est refusée.

4. Idée : une colonne omise prend sa valeur par défaut (DEFAULT), ou NULL si elle n'en a pas.

INSERT INTO Reclamation (dateRec, objet,
                         cinClient)
VALUES ('2026-05-04', 'Coupure de ligne',
        '07123456');

La réclamation reçoit le numéro 59 et l'état « O », valeur par défaut de etat.

2 Drill BD-G.2 — UPDATE sans WHERE : toute la table est modifiée
Entraînement 02 / 05

Drill BD-G.2 — UPDATE sans WHERE : toute la table est modifiée

3 questionsCorrigé masqué

Une librairie enregistre ses articles dans la table Produit ( refProd , designation , prix , categorie ), le prix étant en dinars. Extrait :

refProddesignationprixcategorie
P01Cahier 200 pages3.200Papeterie
P02Stylo bleu0.750Papeterie
P03Clé USB 32 Go18.500Informatique
P04Calculatrice42.000Informatique
P05Classeur5.400Papeterie

On souhaite augmenter de 10 % le prix des articles de la catégorie « Papeterie ». Un employé exécute la requête UPDATE Produit SET prix = prix * 1.1;

  1. Donner les prix des cinq articles après l'exécution de cette requête.
  2. Écrire la requête correcte et donner les prix qu'elle aurait produits à partir de l'extrait initial.
  3. La requête erronée ayant déjà été exécutée, écrire une requête qui rétablit les prix des articles qui ne sont pas de la catégorie « Papeterie ».
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : sans WHERE, UPDATE s'applique à toutes les lignes de la table. Tous les prix sont multipliés par 1,1 : P01 3,520 ; P02 0,825 ; P03 20,350 ; P04 46,200 ; P05 5,940.

2. Idée : la condition sur la catégorie limite la mise à jour aux articles visés.

UPDATE Produit
SET prix = prix * 1.1
WHERE categorie = 'Papeterie';

Prix obtenus : P01 3,520 ; P02 0,825 ; P05 5,940 ; P03 et P04 restent à 18,500 et 42,000.

3. Idée : la multiplication par 1,1 se défait par une division par 1,1, sur les seules lignes modifiées à tort.

UPDATE Produit
SET prix = prix / 1.1
WHERE categorie <> 'Papeterie';

20,350÷1,1=18,50020{,}350 \div 1{,}1 = 18{,}500 et 46,200÷1,1=42,00046{,}200 \div 1{,}1 = 42{,}000 : les prix initiaux sont retrouvés.

3 Drill BD-G.3 — suppression sur trois niveaux : des petites-filles vers la mère
Entraînement 03 / 05

Drill BD-G.3 — suppression sur trois niveaux : des petites-filles vers la mère

6 questionsCorrigé masqué

Un hôpital utilise la base suivante, dont les clés étrangères sont déclarées sans ON DELETE CASCADE :

  • Service ( codeServ , libServ )
  • Medecin ( matMed , nomMed , codeServ# )
  • Consultation ( numCons , dateCons , tarif , matMed# )
  • Ordonnance ( numOrd , dateOrd , numCons# )

Le service de pneumologie, de code « PNE », est transféré vers un autre hôpital avec ses médecins et leurs dossiers.

  1. Écrire les requêtes SQL permettant de supprimer de la base toutes les données relatives à ce service.
  2. Que se passe-t-il si l'on exécute d'abord la requête DELETE FROM Service WHERE codeServ = 'PNE'; ?
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : on remonte la chaîne des clés étrangères depuis le bas : ordonnances, consultations, médecins, puis le service. Les ordonnances ne connaissent que numCons : il faut deux sous-requêtes imbriquées pour atteindre le service.

DELETE FROM Ordonnance
WHERE numCons IN (
    SELECT numCons FROM Consultation
    WHERE matMed IN (
        SELECT matMed FROM Medecin
        WHERE codeServ = 'PNE'));
DELETE FROM Consultation
WHERE matMed IN (SELECT matMed FROM Medecin
                 WHERE codeServ = 'PNE');
DELETE FROM Medecin
WHERE codeServ = 'PNE';
DELETE FROM Service
WHERE codeServ = 'PNE';

2. Elle est refusée : des médecins référencent encore le service « PNE » par leur clé étrangère codeServ, et l'intégrité référentielle interdit de supprimer une ligne mère encore référencée.

4 Drill BD-G.4 — ON DELETE CASCADE : quelles tables sont touchées ?
Entraînement 04 / 05

Drill BD-G.4 — ON DELETE CASCADE : quelles tables sont touchées ?

4 questionsCorrigé masqué

La base d'un foyer culturel a été créée par les requêtes suivantes :

CREATE TABLE Club (
  idClub CHAR(2) PRIMARY KEY,
  nomClub VARCHAR(30) NOT NULL);
CREATE TABLE Adherent (
  numAdh INT PRIMARY KEY,
  nomAdh VARCHAR(40) NOT NULL,
  idClub CHAR(2) REFERENCES Club (idClub)
    ON DELETE CASCADE);
CREATE TABLE Activite (
  codeAct CHAR(2) PRIMARY KEY,
  libAct VARCHAR(30) NOT NULL);
CREATE TABLE Inscription (
  numAdh INT REFERENCES Adherent (numAdh)
    ON DELETE CASCADE,
  codeAct CHAR(2) REFERENCES Activite (codeAct),
  dateIns DATE,
  PRIMARY KEY (numAdh, codeAct));
  1. En supprimant un adhérent, quelles sont les tables touchées ? Justifier.
  2. En supprimant un club, quelles sont les tables touchées ? Justifier.
  3. L'activité « A3 » compte des inscrits. La requête DELETE FROM Activite WHERE codeAct = 'A3'; est-elle exécutée ? Justifier.
  4. Écrire les requêtes qui suppriment l'activité « A3 » ainsi que ses inscriptions.
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : suivre, depuis la table supprimée, chaque clé étrangère qui la référence et regarder si elle porte ON DELETE CASCADE. Tables touchées : Adherent (directement) et Inscription, dont la clé étrangère numAdh est déclarée ON DELETE CASCADE : les inscriptions de l'adhérent sont supprimées.

2. Club (directement), Adherent (cascade sur idClub) et Inscription : la suppression des adhérents du club déclenche à son tour la cascade sur numAdh.

3. Non : la clé étrangère codeAct de Inscription n'a pas l'option ON DELETE CASCADE ; tant que des inscriptions référencent « A3 », sa suppression viole l'intégrité référentielle.

4. Idée : sans cascade, on supprime d'abord les lignes filles.

DELETE FROM Inscription
WHERE codeAct = 'A3';
DELETE FROM Activite
WHERE codeAct = 'A3';
5 Drill BD-G.5 — mise à jour sur une période : colonne date-heure et BETWEEN
Entraînement 05 / 05

Drill BD-G.5 — mise à jour sur une période : colonne date-heure et BETWEEN

3 questionsCorrigé masqué

Une station météo enregistre ses relevés dans les tables Capteur ( idCapt , refCapt , lieu ) et Mesure ( idMes , valeur , dateHeureMes , idCapt# ), où dateHeureMes contient la date et l'heure du relevé. Extrait de Mesure :

idMesvaleurdateHeureMesidCapt
121.52026-03-02 23:40:006
219.02026-03-03 08:15:006
324.52026-03-05 14:30:006
417.02026-03-07 07:05:006
526.02026-03-07 16:45:006
622.02026-03-05 10:00:002
720.52026-03-08 09:10:006

En raison d'un défaut d'étalonnage, on se propose de diminuer de 1,5 les mesures du capteur 6 enregistrées entre le 3 mars 2026 et le 7 mars 2026, ces deux journées comprises. Un technicien propose la requête R :

UPDATE Mesure
SET valeur = valeur - 1.5
WHERE idCapt = 6
  AND dateHeureMes BETWEEN '2026-03-03'
                       AND '2026-03-07';
  1. Quelles lignes de l'extrait la requête R modifie-t-elle ?
  2. Expliquer pourquoi ce n'est pas le résultat attendu.
  3. Écrire une requête correcte et donner les nouvelles valeurs des lignes modifiées.
Voir la correction commentéeAprès avoir posé votre démarche

1. R modifie les lignes 2 et 3 seulement.

2. Idée : comparée à une colonne date-heure, la date '2026-03-07' vaut '2026-03-07 00:00:00'. La borne supérieure de BETWEEN est donc le 7 mars à minuit : les relevés du 7 mars à 07:05 (ligne 4) et à 16:45 (ligne 5) sont exclus alors que la journée du 7 mars devait être comprise.

3. On compare la seule partie date du champ :

UPDATE Mesure
SET valeur = valeur - 1.5
WHERE idCapt = 6
  AND DATE(dateHeureMes) BETWEEN '2026-03-03'
                             AND '2026-03-07';

ou, sans fonction, l'intervalle dateHeureMes >= '2026-03-03' AND dateHeureMes < '2026-03-08'. Lignes modifiées : 2 (17,5), 3 (23,0), 4 (15,5) et 5 (24,5) ; la ligne 1 (2 mars), la ligne 6 (capteur 2) et la ligne 7 (8 mars) ne changent pas.

Relier ce raisonnement au bac

Choisis une filière pour voir les sujets qui étayent ce scénario.