Exercice 2 Nouvelle Calédonie – Bac NSI 2025 – Jour 2
mots clés: SQL, programmation, bugs
🔎 Voir les exercices similaires ↓
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_client | nom | prenom | telephone | |
| 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 |
| 25189 | Kanek | Elise | ekanek@mail.fr | 0600112233 |
| 25322 | Shar | Sofia | shs@fmail.fr | 0644332211 |
| … | … | … | … | … |
| produit | |||
|---|---|---|---|
| ref_produit | designation | type | prix_unitaire |
| 85235 | Marteau TAP | Outillage | 15.89 |
| 86782 | Rouleau peinture | Outillage | 9.55 |
| 89363 | Niveau à bulle | Outillage | 8.2 |
| 89552 | Clous inox | Visserie | 4.5 |
| 89588 | Sac sable | Materiau | 11.6 |
| … | … | … | … |
| remise | ||||
|---|---|---|---|---|
| ref_remise | designation | valeur | date_debut | date_fin |
| 289 | Client en or | 25.0 | 2025/01/01 | 2025/12/31 |
| 326 | Fin de serie | 40.0 | 2025/01/01 | 2025/12/31 |
| 275 | Jour fou | 30.0 | 2025/03/17 | 2025/03/19 |
| 263 | Soldes hiver | 20.0 | 2025/01/01 | 2025/02/01 |
| … | … | … | … | … |
| vente | |||||
|---|---|---|---|---|---|
| ref_vente | date | ref_produit | ref_client | quantité | ref_remise |
| 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 |
| … | … | … | … | … | … |
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.
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.
À 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.
É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’.
É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.
É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.
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[...][...]
Recopier et compléter la ligne 2 du code de la fonction select_tel.
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.
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.
Écrire le code en Python de la fonction nb_produits.
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]
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.
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
🔎 Exercices sur des thèmes similaires
-
Asie 2024 – jour 1 – exercice 3
programmation, POO, BDD, SQL — Difficulté : 🔥🔥🔥🔥🔥 -
Métropole 2025 – jour 2 – exercice 2
BDD, SQL, programmation — Difficulté : 🔥🔥🔥🔥🔥 -
Polynésie 2025 – jour 2 – exercice 2
programmation, POO, BDD, SQL — Difficulté : 🔥🔥🔥🔥🔥 -
Amérique du Nord 2024 – jour 1 – exercice 3
programmation, modularité, BDD, SQL — Difficulté : 🔥🔥🔥🔥🔥 -
Centres étrangers 2024 – jour 1 – exercice 3
programmation, POO, BDD, SQL — Difficulté : 🔥🔥🔥🔥🔥 -
Asie 2024 – jour 2 – exercice 3
BDD, SQL, programmation — Difficulté : 🔥🔥🔥🔥🔥