Exercice 2 Nouvelle Calédonie – Bac NSI 2025 – Jour 2

🔥🔥🔥🔥🔥
On manipule une base de données de magasin et on écrit des requêtes SQL pour ajouter, modifier et retrouver des informations, tout en respectant les clés et l'intégrité. Puis on refait des opérations équivalentes en Python avec des dictionnaires en gérant les erreurs et les suppressions interdites.

mots clés: SQL, programmation, bugs

🔎 Voir les exercices similaires ↓

📘 Sujet PDF

Nouvelle Calédonie – Bac NSI 2025 – Jour 2 Énoncé de l'exercice 2

Cet exercice porte sur les bases de données et la programmation Python et la gestion de bugs.

Dans cet exercice, on pourra utiliser les clauses du langage SQL pour :

  • construire des requêtes d’interrogation à l’aide de SELECT, FROM, WHERE (avec les opérateurs logiques AND, OR) et JOIN ... ON ;

  • construire des requêtes d’insertion et de mise à jour à l’aide de UPDATE, INSERT et DELETE ;

  • affiner les recherches à l’aide de DISTINCT et ORDER BY.

Un magasin de bricolage utilise une base de données constituée de quatre tables dont voici des extraits.

client
ref_clientnomprenomemailtelephone
25123RenaudMartinerenaudm@tmail.com0601020304
25137DupontJacquesdj@mail.fr0604030201
25145PasteurEmilepasteur0@dmail.fr0611121314
25149EiffelFranckeiffel95@popmail.fr0614131211
25189KanekEliseekanek@mail.fr0600112233
25322SharSofiashs@fmail.fr0644332211
……………
produit
ref_produitdesignationtypeprix_unitaire
85235Marteau TAPOutillage15.89
86782Rouleau peintureOutillage9.55
89363Niveau à bulleOutillage8.2
89552Clous inoxVisserie4.5
89588Sac sableMateriau11.6
…………
remise
ref_remisedesignationvaleurdate_debutdate_fin
289Client en or25.02025/01/012025/12/31
326Fin de serie40.02025/01/012025/12/31
275Jour fou30.02025/03/172025/03/19
263Soldes hiver20.02025/01/012025/02/01
……………
vente
ref_ventedateref_produitref_clientquantitéref_remise
256312025/03/1686782251232289
256322025/03/1689363251231289
256332025/03/1785235251491326
256342025/03/1889588251455275
………………
  • L’attribut ref_client est une clé primaire de la table client ;

  • l’attribut ref_produit est une clé primaire de la table produit ;

  • l’attribut ref_remise est une clé primaire de la table remise ;

  • l’attribut ref_vente est une clé primaire de la table vente ;

  • dans la table remise, l’attribut valeur correspond au taux de remise appliqué, exprimé en pourcentage.

  1. Expliquer le rôle d’une clé primaire et rappeler la contrainte dans le choix de celle-ci.

Dans la table vente, les attributs ref_produit et ref_client sont des clés étrangères qui référencent respectivement les attributs ref_produit de la table produit et ref_client de la table client.

  1. À l’aide des extraits de tables, détailler un achat d’Émile Pasteur en précisant :

    • la date de son achat ;

    • le ou les article(s) acheté(s) ;

    • si c’est le cas, le taux de remise dont il a bénéficié.

Un nouveau client doit être entré dans la base, il s’agit de Gilles Bertaut, son email est gbertaut@fmail.fr et son numéro de téléphone est 0641424344. Son identifiant (ref_client) dans la base sera 25345.

  1. Écrire une requête SQL permettant cet ajout.

Une correction est à apporter dans la base, l’email de la cliente Shar Sofia n’a pas été correctement saisi, voici son email correct : ‘shars@fmail.fr’.

  1. Écrire une requête SQL permettant cette mise à jour.

Dans la base de données, toutes les dates sont de type chaîne de caractères au format 'aaaa/mm/jj'. Cela permet de comparer des dates entre elles : par exemple l’opération '2025/04/12' < '2025/05/03' est vraie puisque la date du 12 avril 2025 est antérieure à celle du 3 mai 2025.

  1. Écrire une requête qui permet d’afficher les attributs ref_client de tous les clients ayant fait un achat à partir du 1er janvier 2025. On souhaite qu’un même client n’apparaisse qu’une seule fois dans cet affichage.

  2. La tondeuse de référence 90222 vendue dans le magasin a un défaut de fabrication. Le responsable doit rappeler tous les clients qui ont acheté cette tondeuse depuis le 15 septembre 2024, date de mise en stock des tondeuses défectueuses. Écrire une requête qui permet d’obtenir le nom et le numéro de téléphone des clients à rappeler.

Dans cette partie on suppose que du code Python associé aux requêtes SQL est exécuté pour réaliser l’objectif souhaité. Pour cela, à chaque table de la base de données est associé un dictionnaire Python qui porte le nom de la table.

Le dictionnaire contient les éléments suivants : cle_primaire : [attribut_1, attribut_2, ...]. L’ordre des attributs est identique à celui des extraits de table présentés en début d’exercice.

Par exemple, pour les tables client et vente, les dictionnaires associés sont les suivants :

client = {25123: ['Renaud', 'Martine', 'renaudm@tmail.com', '0601020304'],
          25137: ['Dupont', 'Jacques', 'dj@mail.fr', '0604030201'],
          25145: ['Pasteur', 'Emile', 'pasteur0@dmail.fr', '0611121314'],
          25149: ['Eiffel', 'Franck', 'eiffel95@popmail.fr', '0614131211']}

vente = {25631: ['2025/03/16', 86782, 25123, 2, 289],
         25632: ['2025/03/16', 89363, 25123, 1, 289],
         25633: ['2025/03/17', 85235, 25149, 1, 326],
         25634: ['2025/03/18', 89588, 25145, 5, 275]}

On considère la fonction Python select_tel ci-dessous. Cette fonction est associée à une requête SQL demandant le numéro de téléphone d’un client connaissant son attribut ref_client. Elle prend en paramètres :

  • client, un dictionnaire associé à la table client ;

  • ref_client, un entier correspondant à l’attribut ref_client d’un client.

Ainsi l’instruction Python select_tel(client, 25137) est associée à la requête SQL : SELECT telephone FROM client WHERE ref_client = 25137;

def select_tel(client, ref_client):
    return client[...][...]
  1. Recopier et compléter la ligne 2 du code de la fonction select_tel.

  2. On considère le code de la fonction select_tel complétée. Ainsi l’exécution de l’instruction select_tel(client, 25137) renvoie le bon résultat '0604030201'. Mais l’exécution de l’instruction select_tel(client, 1234) provoque l’erreur ci-dessous :

KeyError: 1234

Expliquer ce qui, concernant le dictionnaire client, est à l’origine de cette erreur et à quelle situation pour le magasin cela correspond.

  1. Recopier le code de la fonction select_tel en proposant une modification pour que la fonction renvoie None plutôt que de provoquer une KeyError dans le cas où la situation précédente se présente.

On souhaite écrire le code de la fonction nb_produits qui prend comme paramètres :

  • vente, un dictionnaire associé à la table vente ;

  • ref_produit, un entier associé à l’attribut ref_produit du dictionnaire à la table vente.

Cette fonction renvoie alors le nombre total de produits de cette référence vendus.

Par exemple pour connaître le nombre de « Marteau TAP » vendu, on écrit l’instruction : nb_produits(vente, 85235) où 85235 est le numéro identifiant le produit « Marteau TAP » et vente est le dictionnaire associé à la table vente.

  1. Écrire le code en Python de la fonction nb_produits.

  2. Dans cette question on considère que les tables de la base de données contiennent exactement ce qui est présenté dans les extraits en début d’exercice. On exécute la requête SQL : DELETE FROM produit WHERE ref_produit = 89363;. Celle-ci n’est pas exécutée et on obtient le message d’erreur foreign key constraint failed. Expliquer pourquoi il est nécessaire que la requête demandée ne soit pas exécutée et qu’elle affiche ce message d’erreur.

On considère le code Python de la fonction associée delete_prod qui permet de supprimer un produit dont la référence est précisée. Cette fonction prend en paramètres :

  • produit, un dictionnaire associé à la table produit ;

  • vente, un dictionnaire associé à la table vente ;

  • ref_produit, un entier correspondant à un attribut ref_produit de la table produit.

def delete_prod(produit, vente, ref_produit):
    del produit[ref_produit]
  1. Réécrire le code de la fonction delete_prod en faisant toutes les modifications et ajouts nécessaires pour qu’à son appel, elle refuse la suppression du produit lorsqu’on rencontre la situation présentée à la question précédente.

▶✅ Correction (cliquer pour afficher) PDF

Nouvelle Calédonie – Bac NSI 2025 – Jour 2 Correction de l'exercice 2

1. Rôle d’une clé primaire

Une clé primaire permet d’identifier de manière unique chaque enregistrement d’une table.

Contrainte : deux enregistrements ne peuvent pas avoir la même valeur de clé primaire (et elle ne peut pas être vide, NULL).

2. Un achat d’Émile Pasteur

Dans la table client, Émile Pasteur a la référence 25145. Dans la table vente, la vente 25634 le concerne :

ref_vente date ref_produit ref_client quantité ref_remise
25634 2025/03/18 89588 25145 5 275

Le produit 89588 est un Sac sable et la remise 275 est « Jour fou », de valeur 30.0, valable du 17 au 19 mars 2025.

Émile Pasteur a acheté le 18 mars 2025 5 sacs de sable avec une remise de 30 %.

3. Ajout d’un client

INSERT INTO client
VALUES (25345, 'Bertaut', 'Gilles', 'gbertaut@fmail.fr', '0641424344');

4. Correction de l’email

UPDATE client
SET email = 'shars@fmail.fr'
WHERE ref_client = 25322;

5. Clients ayant acheté depuis le 1er janvier 2025

SELECT DISTINCT ref_client
FROM vente
WHERE date >= '2025/01/01';

6. Clients à rappeler pour la tondeuse 90222

SELECT client.nom, client.telephone
FROM client
JOIN vente ON client.ref_client = vente.ref_client
WHERE vente.ref_produit = 90222 AND vente.date >= '2024/09/15';

7. Fonction select_tel

def select_tel(client, ref_client):
    return client[ref_client][3]

8. Erreur KeyError: 1234

1234 n’est pas une clé du dictionnaire client : aucun client n’a la référence 1234. Pour le magasin, cela correspond à une recherche portant sur un client qui n’existe pas dans la base.

9. select_tel sans KeyError

def select_tel(client, ref_client):
    if ref_client in client:
        return client[ref_client][3]
    else:
        return None

10. Fonction nb_produits

def nb_produits(vente, ref_produit):
    total = 0
    for ref_vente in vente:
        if vente[ref_vente][1] == ref_produit:
            total = total + vente[ref_vente][3]
    return total

11. Erreur foreign key constraint failed

Le produit 89363 est référencé par la vente 25632 (clé étrangère ref_produit). Si on le supprimait, cette vente ferait référence à un produit qui n’existe plus : la base deviendrait incohérente. Le SGBD refuse la suppression pour garantir l’intégrité référentielle.

12. Fonction delete_prod

def delete_prod(produit, vente, ref_produit):
    for ref_vente in vente:
        if vente[ref_vente][1] == ref_produit:
            print('foreign key constraint failed')
            return None
    del produit[ref_produit]

Une erreur, un oubli ? Écrivez-moi : frederic.peuriere@lfcl.pt

💻 Console Python (cliquer pour afficher)

🔎 Exercices sur des thèmes similaires