TNSI Cours SQLV1 2022
TNSI Cours SQLV1 2022
Introduction
Dans un chapitre précédent, nous avons présenté les problématiques des Systèmes de Gestion de Bases de
Données (SGBD) et le modèle relationnel qui est le principal modèle logique de structuration des données
utilisé depuis les années 1970. Le langage SQL permet de définir et manipuler ces données, il a été déve-
loppé chez IBM sur le SGBD System R.
Les exercices du cours peuvent être testés dans le fichier Capytale d’adresse :
https: // capytale2. ac-paris. fr/ web/ c/ 7a2b-610499
Dans ce chapitre nous utiliserons les termes de table, ligne, colonne plutôt que leurs équivalents relation,
nuplet, attribut.
Sources :
• « Manuel de NSI » de T. Balabonski, S. Conchon, JC. Filliâtre, [Link] aux éditions Ellipse.
• « Cours de Terminale NSI » de Gilles Lassus : https: // glassus. github. io/ terminale_ nsi/ .
☞ Les requêtes qui permettent de définir et modifier le schéma de la base de données, constituent
l’aspect Data Definition Language de SQL. Cette partie n’est pas au programme de terminale NSI.
☞ Les requêtes qui permettent d’extraire des données ou de modifier les contenus des tables (mais pas
leur schéma), constituent l’aspect Data Modification Language de SQL. Le programme de terminale
NSI s’intéresse uniquement à cette partie.
☞ Un client en ligne [Link] Il suffit d’ouvrir la base puis de saisir les requêtes
dans la console. Quand la session est terminée, on pense à sauvegarder ses requêtes dans un fichier
texte, d’extension .sql.
☞ Le client fourni dans le type d’activité SQL du service Capytale de votre ENT. L’avantage est de
pouvoir enregistrer toutes les requêtes d’une session. Le fichier avec la base de données est attaché
à l’activité.
poste
int id_poste PK clef primaire
text num_serie
text nom
modele
systeme
int id_modele PK clef primaire
int id_systeme PK clef primaire
text nom
text nom
text fabricant
text version
int annee
• contrainte de relation avec déclaration d’une clef primaire pour chaque relation ;
• contrainte d’intégrité référentielle dans la déclaration des éventuelles clefs étrangères avec les ré-
férences aux clefs primaires d’autres relations qui leur sont liées.
Voici un exemple de requêtes permettant de créer le schéma relationnel de la base [Link] repré-
sentée sur le graphique 1 page 4. On peut noter que les relations/tables modele et systeme sont créées
avant la relation poste qui leur fait référence.
CREATE TABLE modele(
id_modele INT PRIMARY KEY,
nom TEXT,
fabricant TEXT,
annee INT
);
Exercice 1
1. Afficher le contenu de la table poste dans le fichier Capytale avec SELECT * FROM poste ;
Quelles autres clefs primaires aurait-on pu choisir dans la table poste ?
Méthode
Pour extraire le contenu de certaines colonnes d’une table, la syntaxe minimale est constituée de la clause
SELECT suivie des noms de colonnes séparés par des virgules puis la clause FROM suivie du nom de la
table.
SELECT colonne1, colonne2, ..., colonnep
FROM table ;
Pour extraire le contenu de toutes les colonnes d’une table, on utilise l’attrape-tout * :
SELECT *
FROM table ;
Remarque 1
• Une requête SELECT renvoie une table dite calculée.
• En considérant une table comme un ensemble, on parle de projection sur la ou les colonnes après
le SELECT.
• La fin d’une requête SQL est marquée par un point virgule, facultatif si la requête est isolée.
• SQL n’est pas sensible à la casse des caractères pour les mots clefs, les noms des tables, des colonnes
(mais la casse est importante pour les valeurs de type TEXT, VARCHAR . . .)
Ainsi SELECT Nom FROM SysTeme ; donne le même résultat que SELECT nom FROM systeme ;.
Néanmoins il est préférable de rester homogène dans son style : on recommande d’écrire les mots
clefs en majuscule et de respecter la casse sur les noms de table ou de colonnes.
Exemple 1
Considérons notre base [Link] dont le schéma relationnel est donné dans le graphique 1 page 4.
1. Pour extraire les colonnes avec le nom du système d’exploitation de la table systeme, on écrira :
3. Pour extraire les colonnes avec le fabricant et l’année de livraison de la table modele, on écrira :
On peut noter avec ce dernier exemple que la table calculée, comporte des doublons. Pour les
éliminer, on peut utiliser la clause DISTINCT.
Méthode
On élimine les doublons dans les lignes du résultat d’une requête en préfixant la liste des colonnes par la
clause DISTINCT :
Exercice 2
Considérons notre base [Link] dont le schéma relationnel est donné dans le graphique 1 page 4.
1. Écrire une requête qui extrait les colonnes id_modele et id_systeme de la table poste, en élimi-
nant les doublons sur les lignes du résultat.
2. Écrire une requête qui extrait les colonnes id_poste, id_modele et id_systeme de la table poste.
Est-il nécessaire d’éliminer les doublons sur les lignes du résultat ?
Exemple 2
Nous avons vu comment extraire certaines colonnes d’un table mais comment sélectionner des lignes ?
1. La requête pour sélectionner toutes les colonnes de la table modele mais seulement les lignes dont
le fabricant est ’hp’ peut s’écrire :
2. La requête pour sélectionner toutes les colonnes de la table modele mais seulement les lignes dont
l’année de livraison est inférieure à 2020 peut s’écrire :
☞ la clause SELECT précise les noms des colonnes sur lesquelles on projette les lignes du résultat ;
☞ la clause WHERE spécifie la condition de sélection que doivent vérifier les lignes du résultat.
On peut composer plusieurs conditions simples avec les opérateurs booléens NOT, AND et OR pour créer
des conditions complexes. Il est recommandé d’utiliser des parenthèses.
Exercice 3
On donne le contenu de la table modele :
Donner les tables calculées pour chacune des requêtes listées dans le point de méthode précédent.
La clause ORDER BY doit être toujours en dernière position dans une requête et c’est la dernière opé-
ration effectuée.
Pour afficher la colonne nom de la table systeme par ordre alphabétique croissant on écrira :
Pour afficher la colonne nom de la table systeme par ordre alphabétique décroissant on écrira :
3. On souhaite récupérer le nom de la ville des centres météorologiques situés à une altitude comprise
entre 700 m et 1200 m. Ecrire la requête SQL correspondante.
4. On souhaite récupérer la liste des longitudes et des noms des villes des centres météorologiques
dont la longitude est supérieure à 5. La liste devra être triée par ordre alphabétique des noms de
ville. Ecrire la requête SQL correspondante.
Méthode
En plus des colonnes de la table, il est possible de préciser comme paramètres de la clause SELECT des
constantes ou des valeurs calculées à partir de valeurs de la table.
On définit ainsi de nouvelles colonnes qu’il est possible de nommer avec AS alias.
Par exemple pour calculer l’âge des modèles d’ordinateur disponibles dans la table modele et nommer
cette nouvelle colonne, on peut écrire :
Méthode
On peut passer comme paramètres de la clause SELECT, des valeurs obtenues à l’aide de fonctions
d’agrégation : elles calculent des valeurs agrégées à partir de l’ensemble des lignes sélectionnées.
☞ SUM(nom_colonne) donne la somme des valeurs de la colonne (si la somme est possible !) ;
☞ AVG(nom_colonne) donne la valeur moyenne de la colonne (si la moyenne est possible !).
Par exemple pour calculer l’année de livraison minimale, l’année maximale et l’âge moyen des modèle
d’ordinateur disponibles dans la table modele, on peut écrire :
Bien entendu, on aimerait calculer ces statistiques sur la table poste contenant les informations sur
les postes, on le fera un peu plus tard après avoir joint les informations des tables poste et modele.
Exercice 5
Considérons notre base [Link] dont le schéma relationnel est donné dans le graphique 1 page 4.
1. Écrire une requête SQL qui permet d’obtenir le nombre de postes dans la table poste pour lesquels
la valeur de l’attribut id_systeme est 5 (système ubuntu en version 18.04 installé).
2. Écrire une requête SQL qui permet d’obtenir la valeur minimale de l’attribut id_poste pour les
postes dont le numéro de série comporte au moins un 4.
Définition 3
Examinons l’extrait de table ci-dessous obtenu en rapprochant les informations contenues dans les tables
poste et systeme de notre base [Link].
On peut observer que le rapprochement des lignes s’est effectué sous la condition d’égalité entre la colonne
de nom id_systeme de la table poste et la colonne de même nom de la table systeme.
Fixons le vocabulaire :
☞ La table rassemblant les informations correspondantes des tables poste et systeme a été obtenue
par jointure de ces deux tables.
☞ La condition de jointure pour sélectionner les lignes est l’égalité entre la valeur d’une clef étran-
gère de la table poste et de la clef primaire référencée dans la table systeme. On peut repérer cette
dépendance entre clef étrangère et primaire dans le schéma relationnel de la base page 4.
La jointure est donc l’opération qui permet de reconstituer l’information séparée entre différentes rela-
tions/tables lors de la normalisation du schéma d’une base de données (voir chapitre SGBD et modèle rela-
tionnel).
graphique 2
☞ On construit une table associant chaque ligne de la table poste à chaque ligne de la table systeme
(produit cartésien) :
FROM poste, systeme
☞ On sélectionne uniquement les lignes pertinentes c’est-à-dire celles où on a une égalité entre la
clef étrangère poste.id_systeme et la clef primaire référencée systeme.id_systeme car ce sont
les attributs qui font un lien logique entre poste et systeme :
WHERE poste.id_systeme = systeme.id_systeme
☞ On projette sur les colonnes (ici toutes) qui nous intéressent après le SELECT.
SELECT *
Les attributs intervenant dans la condition de jointure peuvent porter, comme dans cet exemple, les
mêmes noms. Pour lever toute ambiguïté, on préfixe chacun par le nom de sa table.
Une première requête de jointure entre les tables poste et systeme serait donc :
Exercice 6
Considérons notre base [Link] dont le schéma relationnel est donné dans le graphique 1 page 4.
1. Écrire une requête SQL qui affiche une nouvelle table qui contient pour chaque poste son identi-
fiant id_poste, son numéro de série, son nom, son modèle, son fabricant et l’année de livraison.
2. Modifier la requête précédente pour ne sélectionner dans le résultat de la jointure que les modèles
de fabricant ’hp’.
3. Modifier la requête précédente pour ordonner les résultats par ordre décroissant d’année de livrai-
son.
☞ chaque ligne de la table cours correspond à un cours de licence d’informatique avec son code
(clef primaire), sa description et son semestre d’enseignement ;
☞ chaque ligne de la table affectation associe à un poste informatique de la table poste identifié
par la clef étrangère id_poste, un cours identifié par la clef étrangère code_cours.
poste
int id_poste PK clef primaire
text num_serie
text nom
modele
systeme
int id_modele PK clef primaire affectation
int id_systeme PK clef primaire
text nom int id_poste FK clef étrangère référence poste(id_poste), membre de la *clef primaire composite (id_poste, code_cours)*
text nom
text fabricant int code_cours FK clef étrangère référence cours(code), membre de la *clef primaire composite (id_poste, code_cours)*
text version
int annee
cours
text code PK clef primaire
text description
text semestre
graphique 3
3. Écrire une requête dont le résultat est une table de colonnes nom_poste, nom_modele , fabricant,
nom_systeme, version dont on donne un extrait. On renommera certaines colonnes avec AS.
4. Écrire une requête dont le résultat est une table avec pour tous les postes affectés au cours "UNIX",
leur nom, celui de leur système d’exploitation et sa version.
5. Écrire une requête qui calcule, pour le cours "Algorithmique et programmation récursive",
le nombre de postes, leur âge moyen, l’âge minimal et l’âge maximal.
6. a. Écrire d’abord une requête qui détermine l’ensemble des postes qui ont été affectés au cours
"UNIX" avec leur nom de poste et leur numéro de série.
b. Écrire ensuite une requête qui détermine l’ensemble des postes qui ont été affectés au cours
"Algorithmique et programmation récursive" avec leur nom de poste et leur numéro
de série.
c. Déduire des questions précédentes une requête qui détermine l’ensemble des postes qui
ont été affectés à la fois au cours "UNIX" et au cours "Algorithmique et programmation
récursive", avec leur nom de poste et leur numéro de série.
Lorsqu’une table intervient plusieurs fois dans une série de jointures, on utilise des alias de
table avec la syntaxe AS alias comme pour les colonnes.
Voir https: // www. tutorialspoint. com/ sqlite/ sqlite_ alias_ syntax. htm
☞ L’insertion sera refusée par le SGBD si elle ne respecte pas les contraintes d’intégrité (relation, do-
maine, référentielle).
Si on ne veut pas tenir compte de l’ordre, il faut expliciter le changement sur l’ordre des attributs. Par
exemple, si on veut inverser l’ordre des attributs, on écrira :
INSERT INTO table(attributn, ..., attribut2, attribut1)
VALUES (valn,........., val2, val1) ;
Exercice 8
On donne une liste de requêtes d’insertion dans la table poste de la base [Link].
2. À propos du problème de sécurité posé par l’injection de code SQL dans une requête d’insertion,
résumer l’explication donnée sur [Link]
of_a_Mom de la planche 327 dessinée par XKCD.
Méthode
Pour supprimer un ensemble de lignes dans une table, on utilise la clause DELETE avec une condition de
sélection pour spécifier la ou les lignes ciblée(s) :
DELETE FROM table WHERE condition ;
Pour supprimer une table de la base, on utilise la clause DROP TABLE.
DROP TABLE table;
Toute suppression doit laisser la base dans un état qui respecte les contraintes d’intégrité référentielle.
Exercice 9
1. Écrire une requête qui supprime les postes de la table ’poste’ dont le numéro de série contient
un ’Z’.
2. La requête DELETE FROM systeme WHERE nom = ’ubuntu’ AND version = ’18.04’ ; est-elle
acceptée par le SGBD ? Expliquez.
3. Écrire une requête qui supprime de la table affectation toutes les affectations de postes au cours
’UNIX’.
4. À partir du schéma relationnel de la base [Link], page 16, déterminer quelle(s) table(s)
pourraient-être supprimée(s) sans risque d’une violation de contrainte d’intégrité référentielle.
Méthode
Pour mettre à jour un attribut d’une table avec une nouvelle valeur pour un ensemble de lignes, on utilise
la clause UPDATE avec une condition de sélection sur la ou les lignes ciblées :
UPDATE table SET attribut = valeur WHERE condition ;
Toute mise à jour doit laisser la base dans un état qui respecte les contraintes d’intégrité référentielle :
on ne peut pas mettre à jour une valeur référencée par une clef étrangère dans un autre table.
Exercice 10
On reprend la base [Link].
1. On a mis à jour tous les postes équipés du système "ubuntu" en version "20.04" avec la version
"22.04".
Écrire une requête SQL qui enregistre cette mise à jour dans la base.
2. Expliquez pourquoi les requêtes ci-dessous échouent en inspectant la base sur Capytale.