<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Terminale/Bases de données et SQL</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Modèle relationnel (tables, attributs, clés primaires<br/>
et étrangères), contraintes d'intégrité, anomalies dans<br/>
un schéma, langage SQL (SELECT, FROM, WHERE, JOIN,<br/>
INSERT, UPDATE, DELETE), services rendus par un SGBD.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q01 : Définition d'un SGBD</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que désigne le sigle SGBD ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un SGBD relationnel (SGBDR) ajoute la gestion du modèle<br/>
relationnel et du langage SQL. Tous les exemples cités<br/>
ci-dessus sont des SGBDR.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Stockage Garanti des Bases Distribuées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sigle inventé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Système de Génération Binaire de Données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sigle inventé. SGBD est lié à la <strong>gestion</strong><br/>
des bases de données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Standard Général des Bibliothèques de Données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sigle inventé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Système de Gestion de Base de Données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un SGBD est un logiciel qui permet de<br/>
stocker, organiser, interroger et sécuriser des<br/>
données. Exemples : MySQL, PostgreSQL, SQLite, Oracle.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q02 : Vocabulaire du modèle relationnel</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans le modèle relationnel, comment appelle-t-on <strong>une ligne</strong><br/>
d'une table ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Vocabulaire du modèle relationnel : <strong>table</strong> (relation),<br/>
<strong>ligne</strong> (n-uplet, enregistrement), <strong>colonne</strong> (attribut),<br/>
<strong>domaine</strong> (type des valeurs), <strong>clé primaire</strong> (identifiant<br/>
unique).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un attribut</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un attribut est une <strong>colonne</strong> (un champ),<br/>
pas une ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un n-uplet (ou enregistrement)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une ligne d'une table relationnelle est<br/>
un n-uplet (en français) ou <em>tuple</em> (en anglais), aussi<br/>
appelé enregistrement. Elle représente une instance<br/>
d'entité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une clé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une clé est une combinaison d'attributs qui<br/>
identifie de manière unique chaque ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un domaine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un domaine est l'ensemble des valeurs possibles<br/>
pour un attribut (par exemple, les entiers naturels<br/>
pour l'âge).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q03 : Clé primaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la propriété fondamentale d'une <strong>clé primaire</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une clé primaire est : (1) unique, (2) non nulle, (3) stable<br/>
dans le temps. Elle peut être composite (composée de<br/>
plusieurs colonnes) si aucune colonne unique ne suffit.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle identifie de manière unique chaque ligne de la table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la clé primaire est par définition<br/>
unique dans la table. Deux lignes ne peuvent jamais<br/>
avoir la même valeur de clé primaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle doit être un nombre entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une clé primaire peut être de n'importe quel<br/>
type (chaîne, code-barre, identifiant composite). Le<br/>
type entier est seulement le plus courant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle peut prendre la valeur NULL</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une clé primaire ne peut <strong>jamais</strong> être<br/>
NULL, sinon elle ne pourrait plus identifier une<br/>
ligne de manière unique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle doit toujours être une seule colonne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une clé primaire peut être <strong>composite</strong> (sur<br/>
plusieurs colonnes). Par exemple, dans une table<br/>
d'inscriptions, le couple (eleve_id, cours_id) peut<br/>
être une clé primaire composite.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q04 : Clé étrangère</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que représente une <strong>clé étrangère</strong> dans une table ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les clés étrangères implémentent les <strong>relations</strong> entre<br/>
tables et permettent au SGBD de garantir l'<strong>intégrité<br/>
référentielle</strong> : on ne peut pas créer une commande pour<br/>
un client inexistant.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un attribut qui référence la clé primaire d'une autre table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la clé étrangère établit un lien<br/>
relationnel entre deux tables. Par exemple, dans une<br/>
table Commandes, l'attribut client_id référence<br/>
la clé primaire de la table Clients.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une clé qui ne peut pas être modifiée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la modification est possible. Le terme<br/>
« étrangère » concerne la référence vers une autre<br/>
table.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une clé importée d'un autre fichier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : « étrangère » ne signifie pas « importée<br/>
d'un fichier ». Elle référence simplement une autre<br/>
<strong>table</strong> dans la même base.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un attribut crypté pour la sécurité</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune notion de chiffrement dans le concept<br/>
de clé étrangère. C'est une notion structurelle, pas<br/>
de sécurité.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q05 : Syntaxe de base de SELECT</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la syntaxe SQL pour récupérer <strong>toutes</strong> les<br/>
colonnes de la table eleves ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : éviter SELECT * en production et lister<br/>
explicitement les colonnes nécessaires. Cela rend le code<br/>
plus robuste aux évolutions de schéma et plus clair.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe SELECT requiert au minimum la<br/>
liste des colonnes (ou *) puis FROM pour la table.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>GET ALL FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : GET n'existe pas en SQL. La commande de<br/>
lecture est SELECT.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>SELECT * FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : * est le joker qui désigne toutes<br/>
les colonnes. FROM indique la table source.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>READ eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : READ n'est pas un mot-clé SQL. La lecture<br/>
se fait avec SELECT.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q06 : Filtrage avec WHERE</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour ne sélectionner que les élèves majeurs de la table<br/>
eleves, quelle requête utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une requête SQL classique a la forme :<br/>
SELECT colonnes FROM table WHERE condition. Les<br/>
conditions multiples se combinent avec AND, OR, NOT.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>FILTER eleves WHERE age &gt;= 18</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : FILTER n'est pas la syntaxe SQL standard.<br/>
On utilise SELECT ... WHERE.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT * FROM eleves CONDITION age &gt;= 18</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CONDITION n'existe pas en SQL. C'est WHERE<br/>
qui introduit la condition.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>SELECT * FROM eleves WHERE age &gt;= 18</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : WHERE introduit la condition de<br/>
filtrage. La syntaxe est WHERE condition, où<br/>
condition utilise les opérateurs SQL standard<br/>
(=, &lt;, &gt;, &lt;=, &gt;=, &lt;&gt;, LIKE, etc.).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT * FROM eleves IF age &gt;= 18</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : IF n'est pas un mot-clé SQL pour le<br/>
filtrage. Le filtre se fait avec WHERE.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q07 : Tri avec ORDER BY</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour afficher les élèves par ordre alphabétique de leur<br/>
nom, on utilise :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour trier par nom puis par prénom : ORDER BY nom, prenom.<br/>
Pour ordre décroissant : ORDER BY nom DESC. On peut<br/>
mélanger : ORDER BY classe ASC, moyenne DESC.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT * FROM eleves ARRANGE BY nom</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ARRANGE BY n'est pas du SQL valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>SELECT * FROM eleves ORDER BY nom</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ORDER BY trie le résultat selon une<br/>
ou plusieurs colonnes. Par défaut, l'ordre est<br/>
ascendant (ASC). Pour un ordre descendant, ajouter<br/>
DESC.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT * FROM eleves SORTED nom</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : SORTED n'existe pas en SQL.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT * FROM eleves SORT BY nom</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : SORT BY n'est pas une syntaxe SQL. Le tri<br/>
se fait avec ORDER BY.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q08 : Contraintes d'intégrité</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'une <strong>contrainte d'intégrité</strong> dans une base de<br/>
données relationnelle ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les contraintes d'intégrité sont <strong>vérifiées<br/>
automatiquement</strong> par le SGBD à chaque modification. Si<br/>
une opération les violerait, elle est rejetée. C'est une<br/>
garantie forte de cohérence.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un mot de passe pour accéder à une table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec l'authentification. Les<br/>
contraintes d'intégrité concernent la cohérence des<br/>
données, pas la sécurité d'accès.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une règle qui restreint les valeurs admissibles dans la base, vérifiée par le SGBD</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les contraintes garantissent la<br/>
cohérence des données. Exemples : NOT NULL (valeur<br/>
obligatoire), UNIQUE (pas de doublon), clé primaire,<br/>
clé étrangère, CHECK (condition arbitraire).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une copie de sauvegarde automatique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec les sauvegardes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un index pour accélérer les requêtes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les index sont des structures auxiliaires<br/>
pour la performance, pas des règles de cohérence.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q09 : Insertion d'une ligne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle commande SQL ajoute une ligne dans une table ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les quatre commandes principales du SQL DML (Data<br/>
Manipulation Language) sont : SELECT (lire),<br/>
INSERT (créer), UPDATE (modifier), DELETE (supprimer).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>INSERT INTO eleves VALUES ('Alice', 17)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : INSERT INTO table VALUES (...) est la<br/>
forme classique. On peut aussi préciser les colonnes :<br/>
INSERT INTO eleves (nom, age) VALUES ('Alice', 17).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>CREATE INTO eleves VALUES ('Alice', 17)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CREATE est utilisé pour créer une table<br/>
(CREATE TABLE), pas pour insérer une ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>PUT INTO eleves VALUES ('Alice', 17)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : PUT n'existe pas en SQL.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>ADD INTO eleves VALUES ('Alice', 17)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ADD n'est pas la syntaxe SQL standard pour<br/>
ajouter une ligne.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q10 : Valeurs atomiques</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans une base relationnelle correctement conçue, on<br/>
attend que chaque attribut contienne une valeur<br/>
<strong>atomique</strong>. Que signifie cette propriété ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Stocker des valeurs non atomiques (listes, couples,<br/>
tableaux) dans une cellule est une anomalie<br/>
fréquente. Cela empêche de filtrer ou de joindre<br/>
facilement la donnée et peut générer des<br/>
redondances et des incohérences.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur doit être un entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune contrainte de type. Une valeur<br/>
atomique peut être une chaîne, un booléen, un<br/>
flottant…</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La valeur n'est pas décomposable en plusieurs informations distinctes (par exemple, on ne stocke pas plusieurs numéros de téléphone dans une même cellule)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un attribut comme<br/>
telephones = "06 12 ; 06 34" mélange deux<br/>
informations dans une cellule, ce qui rend les<br/>
requêtes difficiles. Il faut alors créer une<br/>
seconde table reliée par une clé étrangère.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur ne peut jamais être modifiée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : « atomique » ne signifie pas<br/>
« immuable ». Les valeurs peuvent évidemment<br/>
être mises à jour avec UPDATE.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur ne peut pas être nulle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport. L'absence de valeur est<br/>
gérée par NULL ou par la contrainte<br/>
NOT NULL.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q11 : Jointure entre deux tables</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour combiner les tables commandes et clients en<br/>
reliant commandes.client_id à clients.id, quelle<br/>
syntaxe utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Différents types de jointures : INNER JOIN (ne garde<br/>
que les lignes appariées), LEFT JOIN (garde toutes les<br/>
lignes de la table de gauche), RIGHT JOIN (symétrique),<br/>
FULL JOIN (les deux côtés).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>SELECT * FROM commandes JOIN clients ON commandes.client_id = clients.id</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est une jointure <strong>interne</strong> explicite.<br/>
Seules les commandes ayant un client correspondant<br/>
apparaissent. Syntaxe préférée à la virgule depuis<br/>
SQL-92.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT * FROM commandes, clients</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette syntaxe produit le <strong>produit cartésien</strong><br/>
(toutes les paires possibles), sans condition de<br/>
jointure. Le résultat est rarement ce qu'on souhaite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT * FROM commandes WITH clients</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : WITH introduit des sous-requêtes nommées<br/>
(CTE), pas des jointures.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT * FROM commandes UNION clients</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : UNION combine deux requêtes en empilant<br/>
leurs résultats (les lignes de l'une après l'autre).<br/>
Pour combiner colonnes côte à côte, c'est JOIN.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q12 : Fonctions d'agrégation</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour calculer la <strong>moyenne des âges</strong> des élèves, quelle<br/>
requête utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les fonctions d'agrégation principales en SQL sont<br/>
COUNT, SUM, AVG, MIN et MAX. Elles<br/>
synthétisent une colonne entière en une seule<br/>
valeur dans le résultat de la requête.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT MOYENNE(age) FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : SQL utilise des mots-clés en anglais. La<br/>
version française n'existe pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT (age) FROM eleves AVERAGE</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe AVERAGE après le FROM n'existe<br/>
pas. Les fonctions d'agrégation s'appliquent à<br/>
l'intérieur du SELECT.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT MEAN(age) FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction de moyenne en SQL standard<br/>
s'appelle AVG, pas MEAN.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>SELECT AVG(age) FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : AVG (<em>average</em>) calcule la moyenne<br/>
arithmétique. Les fonctions d'agrégation principales<br/>
sont COUNT, SUM, AVG, MIN, MAX.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q13 : Combiner WHERE et ORDER BY</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle requête renvoie les noms des élèves majeurs,<br/>
classés par âge <strong>décroissant</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'ordre canonique des clauses dans une requête<br/>
d'interrogation est : SELECT … FROM … WHERE …<br/>
ORDER BY …. Le mot-clé DESC après ORDER BY<br/>
indique un tri décroissant ; ASC (par défaut)<br/>
indique un tri croissant.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT nom FROM eleves ORDER BY age DESC WHERE age &gt;= 18</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'ordre des clauses est imposé en SQL.<br/>
WHERE se place avant ORDER BY.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>SELECT nom FROM eleves WHERE age &gt;= 18 ORDER BY age DESC</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : WHERE filtre les lignes<br/>
(majeurs), puis ORDER BY age DESC les trie par<br/>
âge décroissant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT nom FROM eleves WHERE age &gt;= 18 ORDER BY age</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans le mot-clé DESC, le tri se fait<br/>
par défaut en ordre croissant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT nom FROM eleves WHERE age &gt;= 18 SORT age DESC</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la clause SORT n'existe pas en SQL<br/>
standard. Il faut utiliser ORDER BY.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q14 : Modification d'une ligne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour augmenter de 1 point la note de l'élève d'identifiant<br/>
42, quelle requête utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Toujours penser à mettre une clause WHERE sur les<br/>
UPDATE et DELETE. <strong>Sans elle, la modification s'applique<br/>
à toutes les lignes</strong> de la table, ce qui est rarement ce<br/>
qu'on veut et souvent catastrophique.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>MODIFY eleves SET note = note + 1 WHERE id = 42</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : MODIFY n'est pas un mot-clé SQL standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>UPDATE eleves SET note = note + 1 WHERE id = 42</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : UPDATE met à jour des lignes<br/>
existantes. La clause SET indique les modifications<br/>
et WHERE filtre les lignes affectées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>UPDATE eleves WHERE id = 42 SET note = note + 1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ordre incorrect des clauses. La syntaxe<br/>
standard est UPDATE table SET ... WHERE ....</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>CHANGE eleves SET note = note + 1 WHERE id = 42</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CHANGE n'est pas un mot-clé SQL standard.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q15 : Suppression de doublons</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour obtenir la liste des <strong>classes différentes</strong> présentes<br/>
dans la table eleves (sans doublons), quelle requête<br/>
utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>DISTINCT agit sur l'ensemble des colonnes<br/>
sélectionnées. Par exemple,<br/>
SELECT DISTINCT nom, prenom FROM eleves ne renverra<br/>
qu'une ligne par couple (nom, prenom) distinct.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>SELECT DISTINCT classe FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : DISTINCT élimine les doublons. Si<br/>
la table contient 30 élèves de la classe « 1NSI »<br/>
et 25 de « TNSI », la requête renvoie deux lignes :<br/>
« 1NSI » et « TNSI ».</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT classe DISTINCT FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : DISTINCT se place <strong>avant</strong> la liste des<br/>
colonnes, juste après SELECT.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT UNIQUE classe FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : UNIQUE est utilisé pour les contraintes au<br/>
moment de la création de table, pas pour la sélection.<br/>
Le mot-clé pour la sélection est DISTINCT.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>SELECT classe FROM eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans DISTINCT, le résultat contiendra une<br/>
entrée par élève, donc beaucoup de doublons.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q16 : Représenter une association multiple</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On souhaite représenter le fait qu'un élève peut<br/>
suivre <strong>plusieurs cours</strong> et qu'un cours peut<br/>
accueillir <strong>plusieurs élèves</strong>. Quel schéma<br/>
relationnel adopter ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une association « plusieurs à plusieurs » se<br/>
représente par une table d'association qui contient<br/>
les clés étrangères des deux entités liées. C'est un<br/>
patron classique du modèle relationnel pour éviter<br/>
les redondances.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Deux tables avec une duplication des cours dans chaque ligne d'élève</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la duplication crée des redondances et<br/>
des anomalies de mise à jour si l'intitulé<br/>
d'un cours change.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une seule table eleves avec autant de colonnes cours_1, cours_2, cours_3 qu'il y a de cours possibles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce schéma est rigide (il faut<br/>
modifier la structure si un nouveau cours<br/>
apparaît) et la plupart des cellules seront<br/>
vides.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une seule table contenant eleve et tous ses cours dans une même cellule</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on viole la propriété d'atomicité des<br/>
attributs et on ne peut plus interroger<br/>
facilement les données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Trois tables eleves(id, nom), cours(id, intitule) et inscriptions(eleve_id, cours_id) reliées par des clés étrangères</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on isole chaque entité dans sa<br/>
table et on crée une table <strong>d'association</strong><br/>
dont chaque ligne représente une inscription<br/>
d'un élève à un cours.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q17 : Recherche avec LIKE</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour trouver tous les élèves dont le nom commence par "Du",<br/>
quelle requête utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les jokers de LIKE : % (zéro ou plus de caractères) et<br/>
_ (un caractère exactement). Pour une recherche<br/>
insensible à la casse, certains SGBD acceptent ILIKE<br/>
(PostgreSQL) ou LIKE avec LOWER() (portable).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>WHERE nom STARTS 'Du'</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : STARTS n'est pas un mot-clé SQL standard.<br/>
Pour cette recherche, on utilise LIKE avec %.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>WHERE nom LIKE 'Du%'</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : LIKE permet la correspondance par<br/>
motif. Le caractère % représente n'importe quelle<br/>
séquence de caractères (zéro ou plus). Donc 'Du%'<br/>
correspond à "Du", "Dupont", "Dubois", etc.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>WHERE nom = 'Du'</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : = teste l'égalité exacte. Cela ne<br/>
renverrait que les élèves dont le nom est <strong>exactement</strong><br/>
"Du", pas ceux qui commencent par "Du".</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>WHERE nom CONTAINS 'Du'</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : CONTAINS est non standard (existant dans<br/>
certains SGBD pour la recherche plein texte). Le SQL<br/>
standard utilise LIKE avec des jokers.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q18 : Suppression d'une ligne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait la requête DELETE FROM eleves; ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Toujours utiliser WHERE avec DELETE, sauf intention<br/>
explicite de tout vider. Beaucoup de SGBD permettent<br/>
d'imposer une clause WHERE obligatoire en mode<br/>
« <em>safe updates</em> » pour éviter les catastrophes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle supprime toutes les lignes de la table eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : DELETE sans clause WHERE vide la<br/>
table (mais la structure reste). C'est l'erreur<br/>
classique en production. Pour supprimer la table<br/>
entière (structure incluse), il faut DROP TABLE eleves.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle supprime la table entière (structure et contenu)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est DROP TABLE qui supprime la structure.<br/>
DELETE FROM ne touche que les lignes, pas le schéma.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle ne fait rien (manque de WHERE)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans WHERE, la requête s'applique à<br/>
<strong>toutes</strong> les lignes. Elle est syntaxiquement valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle lève une erreur SQL</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe est valide. Aucune erreur n'est<br/>
levée : c'est précisément le piège.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q19 : Services rendus par un SGBD</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel des éléments suivants n'est <strong>pas</strong> un<br/>
service rendu par un système de gestion de bases de<br/>
données ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les services principaux d'un SGBD sont la<br/>
persistance, la gestion des accès concurrents,<br/>
l'efficacité du traitement des requêtes et la<br/>
sécurisation des accès. Le programme officiel<br/>
demande de les <strong>identifier</strong>, sans en détailler le<br/>
fonctionnement interne.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La gestion des accès concurrents par plusieurs utilisateurs ou programmes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est bien un service du SGBD, qui évite<br/>
les incohérences quand plusieurs requêtes<br/>
modifient les mêmes données simultanément.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La persistance des données (les données survivent à l'arrêt du programme)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est bien un service du SGBD, qui assure<br/>
le stockage durable des données sur disque.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La compilation du code source d'un programme Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la compilation de code Python<br/>
n'a aucun rapport avec un SGBD. C'est le rôle de<br/>
l'interpréteur Python ou d'un compilateur, pas<br/>
du gestionnaire de bases de données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La sécurisation des accès (authentification, droits par utilisateur)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est bien un service du SGBD, qui<br/>
contrôle qui peut lire ou modifier quoi.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q20 : Intégrité référentielle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle situation viole l'<strong>intégrité référentielle</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'intégrité référentielle est garantie par les<br/>
contraintes FOREIGN KEY. À la suppression d'un client,<br/>
on peut configurer ON DELETE CASCADE (supprimer aussi<br/>
les commandes), ON DELETE RESTRICT (interdire la<br/>
suppression s'il y a des commandes), etc.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avoir deux clients avec le même nom</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas une violation tant que la clé<br/>
primaire (l'id) est unique. Le nom peut être en<br/>
double.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Insérer une commande avec un client_id qui n'existe pas dans la table clients</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la clé étrangère client_id doit<br/>
pointer vers une ligne existante de la table<br/>
clients. Sinon, on a une référence orpheline,<br/>
violation typique de l'intégrité référentielle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Insérer une commande sans préciser la quantité</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est une violation de contrainte NOT NULL,<br/>
pas d'intégrité référentielle. Cette dernière concerne<br/>
les références entre tables.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier les commandes par date</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un tri ne viole aucune contrainte.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q21 : Sous-requête</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que renvoie cette requête ?</p>
<p>`<code><br/>
SELECT nom FROM eleves<br/>
WHERE moyenne &gt; (SELECT AVG(moyenne) FROM eleves);<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>On peut utiliser &gt;=, &lt;, =, IN avec une sous-requête.<br/>
La sous-requête est exécutée <strong>une fois</strong> ici (elle ne<br/>
dépend pas de la ligne courante), donc le SGBD optimise<br/>
automatiquement.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les moyennes des élèves au-dessus de zéro</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la condition &gt; ne porte pas sur zéro mais<br/>
sur la valeur de la sous-requête.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur (sous-requête non autorisée)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les sous-requêtes sont parfaitement<br/>
autorisées en SQL. C'est une fonctionnalité<br/>
essentielle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La moyenne des moyennes des élèves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : AVG(moyenne) calcule effectivement la<br/>
moyenne des moyennes, mais la requête principale<br/>
renvoie les <strong>noms</strong> des élèves dépassant cette<br/>
moyenne, pas le calcul lui-même.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les noms des élèves dont la moyenne est strictement supérieure à la moyenne de la classe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la sous-requête calcule la moyenne<br/>
globale, et la requête principale filtre les élèves<br/>
au-dessus. C'est un usage très courant des<br/>
sous-requêtes pour comparer à un agrégat.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q22 : Détection d'une redondance</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une table commandes(id, client_id, nom_client, prenom_client, produit, prix)<br/>
pose un problème classique de schéma. Lequel ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La normalisation vise à éliminer les redondances pour<br/>
garantir la <strong>cohérence</strong>. Si on stocke le nom du client<br/>
dans chaque commande et que le client se marie, il faut<br/>
mettre à jour toutes ses commandes, risqué et coûteux.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La clé primaire est mal choisie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : id est un choix raisonnable de clé primaire<br/>
pour des commandes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les informations du client (nom, prénom) sont dupliquées à chaque commande, ce qui crée des incohérences potentielles si les noms sont mal mis à jour</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est une <strong>redondance</strong><br/>
classique. Le nom et le prénom dépendent de<br/>
client_id, pas de l'id de commande. Il<br/>
faudrait les mettre dans une table clients<br/>
séparée et conserver uniquement la clé<br/>
étrangère client_id dans commandes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le prix devrait être stocké séparément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le prix peut varier d'une commande à l'autre<br/>
(promotions, historiques) et a sa place dans commandes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La table contient trop de colonnes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le nombre de colonnes n'est pas un problème<br/>
en soi. Le problème est ailleurs.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q23 : Différence entre INNER et LEFT JOIN</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre INNER JOIN et LEFT JOIN ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le JOIN simple (équivalent de INNER JOIN)<br/>
apparie les lignes selon la condition ON. Le<br/>
LEFT JOIN étend ce comportement en conservant<br/>
aussi les lignes de gauche sans correspondance, en<br/>
les complétant par des NULL côté droit.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>INNER JOIN ne garde que les paires appariées ; LEFT JOIN garde toutes les lignes de la table de gauche, complétées par NULL à droite si aucune correspondance</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour lister tous les clients avec<br/>
leurs commandes (ou pas), on utilise LEFT JOIN. Avec<br/>
INNER JOIN, les clients sans commande disparaissent<br/>
du résultat.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune, ce sont des synonymes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ils diffèrent sur la gestion des lignes non<br/>
appariées de la table de gauche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>LEFT JOIN ne fonctionne que sur des tables triées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune contrainte de tri n'est requise pour<br/>
un LEFT JOIN.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>INNER JOIN est plus rapide que LEFT JOIN</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la performance dépend du SGBD et du contexte.<br/>
La différence sémantique est ce qui compte avant<br/>
tout.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q24 : Problème de concurrence</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Sans isolation des transactions, deux transactions<br/>
simultanées qui modifient le même compte bancaire peuvent<br/>
provoquer :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La gestion des accès concurrents est l'un des<br/>
services principaux d'un SGBD. Le système prend en<br/>
charge l'enchaînement des opérations pour garantir<br/>
la cohérence des données, même quand plusieurs<br/>
utilisateurs ou programmes les manipulent en même<br/>
temps.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une perte de mise à jour : l'effet d'une transaction est annulé par l'autre, faisant disparaître un dépôt</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : si T1 lit le solde (1000), puis T2<br/>
lit aussi (1000), puis T1 ajoute 100 et écrit<br/>
1100, puis T2 ajoute 50 et écrit 1050, le dépôt<br/>
de T1 est perdu. C'est la <strong>perte de mise à jour</strong><br/>
classique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur de syntaxe SQL</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe est correcte. Le problème est de<br/>
<strong>cohérence</strong>, pas syntaxique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une duplication automatique des données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune duplication automatique. C'est plutôt<br/>
de la perte d'information.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une accélération de l'exécution des deux transactions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans isolation, on a au contraire des<br/>
incohérences. La gestion correcte est plus lente mais<br/>
fiable.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q25 : Index</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi crée-t-on des <strong>index</strong> sur les colonnes<br/>
fréquemment utilisées dans des WHERE ou des jointures ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Compromis classique : un index accélère <strong>les lectures</strong><br/>
mais ralentit <strong>les écritures</strong> (chaque insertion ou mise<br/>
à jour doit aussi mettre à jour l'index). On crée donc des<br/>
index uniquement sur les colonnes vraiment souvent<br/>
interrogées.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour accélérer la recherche en évitant un parcours complet de la table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un index est une structure<br/>
auxiliaire qui permet de retrouver rapidement<br/>
les lignes correspondant à une valeur donnée,<br/>
sans avoir à parcourir toute la table.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour économiser de l'espace de stockage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'inverse, un index <strong>consomme</strong> de<br/>
l'espace supplémentaire. Le bénéfice est ailleurs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour rendre les données automatiquement triées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un index trie en interne, mais les données<br/>
de la table elle-même restent dans leur ordre<br/>
original.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour chiffrer les données sensibles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les index sont des structures de performance,<br/>
pas de sécurité.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q26 : Regroupement avec GROUP BY</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour obtenir le <strong>nombre d'élèves par classe</strong> dans la<br/>
table eleves(id, nom, classe), quelle requête utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma général : SELECT colonne, AGREGATION(...) FROM<br/>
table GROUP BY colonne. Toutes les colonnes du SELECT<br/>
qui ne sont pas dans une fonction d'agrégation doivent<br/>
apparaître dans le GROUP BY. C'est la règle dite<br/>
« des colonnes visibles ».</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
SELECT classe, COUNT(*)<br/>
FROM eleves;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans GROUP BY, mélanger une colonne et une<br/>
fonction d'agrégation provoque une erreur SQL ou un<br/>
résultat incohérent (selon le SGBD). Il faut grouper<br/>
explicitement par classe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
SELECT DISTINCT classe, COUNT(*)<br/>
FROM eleves;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : DISTINCT élimine les doublons après calcul,<br/>
il ne sert pas à regrouper pour appliquer une<br/>
agrégation. La syntaxe correcte est GROUP BY.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
SELECT classe, COUNT(eleves)<br/>
FROM eleves<br/>
GROUP BY classe;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : COUNT(eleves) n'est pas valide :<br/>
eleves est le nom de la table, pas une colonne.<br/>
Pour compter les lignes, on utilise COUNT(*) ou une<br/>
colonne précise (COUNT(id)).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code><br/>
SELECT classe, COUNT(*)<br/>
FROM eleves<br/>
GROUP BY classe;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : GROUP BY regroupe les lignes par<br/>
valeur distincte de classe. La fonction d'agrégation<br/>
COUNT(*) compte les lignes de chaque groupe. Le<br/>
résultat est une ligne par classe avec son effectif.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q27 : HAVING vs WHERE</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour ne garder que les classes ayant <strong>au moins<br/>
25 élèves</strong>, on doit filtrer un résultat agrégé. Quelle<br/>
est la requête correcte ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ordre canonique des clauses :<br/>
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY.<br/>
Mnémonique : WHERE filtre les lignes individuelles avant<br/>
regroupement ; HAVING filtre les groupes après agrégation.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
SELECT classe<br/>
FROM eleves<br/>
GROUP BY classe<br/>
WHERE COUNT(*) &gt;= 25;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la clause WHERE doit toujours apparaître<br/>
<strong>avant</strong> GROUP BY dans la syntaxe SQL. De plus,<br/>
on ne peut pas y mettre une fonction d'agrégation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
SELECT classe, COUNT(<em>)<br/>
FROM eleves<br/>
WHERE COUNT(</em>) &gt;= 25<br/>
GROUP BY classe;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : WHERE ne peut pas porter sur une fonction<br/>
d'agrégation, qui n'est calculée qu'<strong>après</strong> le<br/>
regroupement. Cette requête échoue avec une erreur<br/>
SQL. C'est précisément le rôle de HAVING.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
SELECT classe, COUNT(<em>)<br/>
FROM eleves<br/>
HAVING classe COUNT(</em>) &gt;= 25;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe est invalide. HAVING doit<br/>
contenir une condition logique, et il manque le<br/>
GROUP BY qui définit les groupes sur lesquels<br/>
porte le HAVING.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code><br/>
SELECT classe, COUNT(<em>)<br/>
FROM eleves<br/>
GROUP BY classe<br/>
HAVING COUNT(</em>) &gt;= 25;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : HAVING filtre les groupes après<br/>
agrégation, contrairement à WHERE qui filtre les<br/>
lignes avant agrégation. Pour porter sur le résultat<br/>
de COUNT(*), il faut utiliser HAVING.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q28 : Propriétés ACID</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Les propriétés ACID des transactions garantissent leur<br/>
bon comportement dans un SGBD. Que désigne le « C » de<br/>
ACID ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les quatre propriétés ACID sont : <strong>Atomicité</strong> (tout<br/>
ou rien), <strong>Cohérence</strong> (contraintes respectées),<br/>
<strong>Isolation</strong> (transactions concurrentes invisibles<br/>
les unes aux autres), <strong>Durabilité</strong> (modifications<br/>
persistées même en cas de panne). Indispensable pour<br/>
les bases métier (banque, santé, stock).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Compression</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la compression est une optimisation de<br/>
stockage, sans rapport avec les transactions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Confidentialité</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la confidentialité relève de la sécurité<br/>
(chiffrement, contrôle d'accès), pas des propriétés<br/>
ACID des transactions. Ce sont deux dimensions<br/>
différentes du SGBD.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Connexion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la connexion à la base est un mécanisme<br/>
d'accès, pas une propriété des transactions. Le<br/>
« C » désigne une propriété logique des transactions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Cohérence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la <strong>cohérence</strong> garantit qu'une<br/>
transaction fait passer la base d'un état cohérent<br/>
(toutes les contraintes respectées) à un autre état<br/>
cohérent. Si une transaction violerait une<br/>
contrainte d'intégrité, elle est rejetée<br/>
intégralement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q29 : DROP, DELETE, TRUNCATE</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre DROP TABLE eleves,<br/>
DELETE FROM eleves et TRUNCATE TABLE eleves ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : utiliser DELETE FROM ... WHERE pour<br/>
des suppressions ciblées et sécurisées ; TRUNCATE pour<br/>
vider rapidement une table en conservant son schéma ;<br/>
DROP TABLE uniquement quand on veut effectivement se<br/>
débarrasser de la table elle-même. Toujours sauvegarder<br/>
avant DROP.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune n'est valide en SQL standard</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les trois sont des commandes SQL valides.<br/>
TRUNCATE est légèrement moins répandu que les<br/>
deux autres, mais reste standard dans la plupart<br/>
des SGBD relationnels.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>DROP et DELETE sont identiques ; seul<br/>
TRUNCATE est différent (il vide aussi les<br/>
fichiers de log)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : DROP TABLE et DELETE FROM ne sont<br/>
<strong>pas</strong> équivalents. Le premier supprime la<br/>
structure de la table ; le second ne supprime<br/>
que les lignes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les trois commandes sont équivalentes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : elles ont des effets très différents,<br/>
comme le détaille la bonne réponse. Confondre<br/>
DROP et DELETE peut être catastrophique en<br/>
production : DROP supprime tout, structure<br/>
comprise.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>DROP TABLE supprime la table entière (structure et<br/>
contenu) ; DELETE FROM (sans WHERE) supprime<br/>
toutes les lignes mais conserve la structure (les<br/>
contraintes et les types restent) ; TRUNCATE TABLE<br/>
vide rapidement le contenu en conservant la<br/>
structure (souvent plus rapide que DELETE)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : trois commandes très différentes.<br/>
DROP est destructif sur le schéma : la table<br/>
n'existe plus du tout après. DELETE est une<br/>
opération transactionnelle au cas par cas (logge<br/>
chaque suppression). TRUNCATE est une opération<br/>
en bloc, sans logging détaillé, généralement plus<br/>
rapide pour vider une grosse table.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q30 : Trace d'une requête SELECT avec WHERE</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère la table eleves suivante :</p>
<p>| id | nom    | classe | moyenne |<br/>
|----|--------|--------|---------|<br/>
| 1  | Alice  | 1A     | 14.5    |<br/>
| 2  | Bob    | 1B     | 9.0     |<br/>
| 3  | Chloé  | 1A     | 16.0    |<br/>
| 4  | David  | 1B     | 13.0    |<br/>
| 5  | Émma   | 1A     | 11.5    |</p>
<p>Que renvoie la requête suivante ?</p>
<p>`<code>sql<br/>
SELECT nom, moyenne<br/>
FROM eleves<br/>
WHERE classe = '1A' AND moyenne &gt;= 12<br/>
ORDER BY moyenne DESC;<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Méthode systématique pour évaluer une requête<br/>
SQL : (1) appliquer le filtre WHERE pour ne<br/>
conserver que les lignes pertinentes ; (2)<br/>
projeter sur les colonnes du SELECT ; (3)<br/>
trier selon ORDER BY si présent. Cette<br/>
séquence d'étapes est l'algèbre relationnelle en<br/>
action.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Cinq lignes (toutes les lignes de la table)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on a oublié le filtrage par WHERE.<br/>
Sans filtre, on aurait bien toutes les<br/>
lignes, mais ici la requête restreint aux<br/>
élèves de 1A avec une moyenne d'au moins<br/>
12.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trois lignes : ('Alice', 14.5),<br/>
('Chloé', 16.0), ('Émma', 11.5)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Émma est en 1A mais sa moyenne<br/>
(11{,}5) est inférieure à 12, donc elle<br/>
ne satisfait pas la condition moyenne &gt;= 12.<br/>
De plus, l'ordre n'est pas décroissant ici.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Deux lignes : ('Chloé', 16.0) puis<br/>
('Alice', 14.5)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse. Étape 1, le filtre<br/>
WHERE classe = '1A' AND moyenne &gt;= 12<br/>
retient les élèves de la classe 1A avec<br/>
une moyenne d'au moins 12 : Alice (14{,}5)<br/>
et Chloé (16). Émma est en 1A mais sa<br/>
moyenne (11{,}5) ne satisfait pas la<br/>
deuxième condition. Étape 2, on ne garde<br/>
que les colonnes nom et moyenne. Étape 3,<br/>
on trie par moyenne DESC : Chloé d'abord,<br/>
puis Alice.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une seule ligne : ('Chloé', 16.0)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Alice satisfait elle aussi les deux<br/>
conditions (14{,}5 \geq 12 et classe<br/>
1A). Elle doit donc apparaître dans le<br/>
résultat, après Chloé du fait du tri<br/>
décroissant.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q31 : Trace d'une jointure</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On dispose des deux tables suivantes :</p>
<p>Table clients :</p>
<p>| id | nom    |<br/>
|----|--------|<br/>
| 1  | Alice  |<br/>
| 2  | Bob    |<br/>
| 3  | Chloé  |</p>
<p>Table commandes :</p>
<p>| id | client_id | produit  |<br/>
|----|-----------|----------|<br/>
| 10 | 1         | Livre    |<br/>
| 11 | 2         | Cahier   |<br/>
| 12 | 1         | Stylo    |</p>
<p>Combien de lignes renvoie la requête suivante ?</p>
<p>`<code>sql<br/>
SELECT c.nom, cmd.produit<br/>
FROM clients c<br/>
JOIN commandes cmd ON c.id = cmd.client_id;<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour faire apparaître Chloé (qui n'a aucune<br/>
commande) dans le résultat, il faudrait<br/>
utiliser un LEFT JOIN. La ligne<br/>
correspondante aurait alors NULL dans la<br/>
colonne cmd.produit. Cela permet de<br/>
répondre à la question « tous les clients,<br/>
avec leurs commandes éventuelles ».</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>2 lignes (une seule par client présent dans<br/>
les commandes)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Alice a <strong>deux</strong> commandes, donc<br/>
elle apparaît deux fois dans le résultat<br/>
(avec 'Livre' et avec 'Stylo'). La<br/>
jointure ne fusionne pas les commandes<br/>
d'un même client.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>3 lignes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la jointure interne (JOIN,<br/>
synonyme de INNER JOIN) ne garde que les<br/>
paires (client, commande) où la condition<br/>
c.id = cmd.client_id est vraie. Alice<br/>
(id 1) a deux commandes (10 et 12),<br/>
Bob (id 2) en a une, Chloé n'en a aucune<br/>
et disparaît du résultat. Total : trois<br/>
lignes. Le résultat est :<br/>
('Alice', 'Livre'), ('Bob', 'Cahier'),<br/>
('Alice', 'Stylo').</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>9 lignes (le produit cartésien 3 × 3)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le résultat sans la<br/>
condition ON c.id = cmd.client_id. Avec<br/>
la condition, on ne garde que les paires<br/>
cohérentes, soit trois lignes ici. Le<br/>
produit cartésien apparaît avec<br/>
FROM clients, commandes (sans JOIN).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>4 lignes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seules trois commandes existent,<br/>
donc au plus trois lignes peuvent<br/>
apparaître. Une ligne supplémentaire<br/>
n'apparaîtrait que si l'on utilisait un<br/>
LEFT JOIN qui inclurait Chloé sans<br/>
commande (avec NULL côté commandes).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q32 : GROUP BY avec HAVING en pratique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Avec la table eleves(id, nom, classe, moyenne)<br/>
contenant trente élèves répartis entre trois<br/>
classes (1A, 1B, 1C), que renvoie la<br/>
requête suivante ?</p>
<p>`<code>sql<br/>
SELECT classe, AVG(moyenne) AS moy_classe<br/>
FROM eleves<br/>
GROUP BY classe<br/>
HAVING AVG(moyenne) &gt; 12<br/>
ORDER BY moy_classe DESC;<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Distinction essentielle : WHERE filtre les<br/>
lignes individuelles <strong>avant</strong> l'agrégation ;<br/>
HAVING filtre les groupes <strong>après</strong><br/>
l'agrégation. Si on voulait restreindre aux<br/>
élèves majeurs avant de calculer les moyennes,<br/>
on aurait combiné les deux :<br/>
WHERE age &gt;= 18 ... HAVING AVG(moyenne) &gt; 12.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La liste des classes dont la moyenne de<br/>
la classe est strictement supérieure à<br/>
12, avec leur moyenne, triée par<br/>
moyenne décroissante</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse. Étape 1, GROUP BY classe<br/>
regroupe les élèves par classe. Étape 2,<br/>
AVG(moyenne) calcule la moyenne de chaque<br/>
groupe. Étape 3, HAVING AVG(moyenne) &gt; 12<br/>
filtre les groupes (et non les lignes<br/>
individuelles) selon cette condition.<br/>
Étape 4, ORDER BY moy_classe DESC trie<br/>
le résultat.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur SQL, car on ne peut pas mettre<br/>
un alias dans ORDER BY</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : SQL autorise tout à fait<br/>
d'utiliser un alias défini dans le<br/>
SELECT (ici moy_classe) au sein de<br/>
ORDER BY. La requête est valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toutes les classes, avec la somme des<br/>
moyennes des élèves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction utilisée est AVG<br/>
(moyenne), pas SUM (somme). Les deux<br/>
fonctions d'agrégation sont distinctes.<br/>
De plus, le HAVING filtrerait certaines<br/>
classes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La liste des élèves dont la moyenne<br/>
individuelle est supérieure à 12</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est ce que ferait un simple<br/>
WHERE moyenne &gt; 12 sans GROUP BY. Ici,<br/>
la fonction d'agrégation AVG(moyenne)<br/>
combinée à GROUP BY classe calcule la<br/>
moyenne <strong>par classe</strong>, pas par élève.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q33 : Notion de vue</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une <strong>vue</strong> (VIEW) en SQL est :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les vues facilitent aussi la <strong>sécurité</strong> : on<br/>
peut accorder l'accès à une vue qui masque<br/>
certaines colonnes sensibles, sans donner<br/>
accès aux tables sous-jacentes. Variante<br/>
avancée : la <strong>vue matérialisée</strong> stocke<br/>
effectivement le résultat, et est rafraîchie<br/>
périodiquement ; elle combine vue et cache.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une requête nommée dont le résultat se<br/>
comporte comme une table virtuelle :<br/>
chaque interrogation de la vue<br/>
réexécute la requête sous-jacente sur les<br/>
données actuelles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on définit une vue avec<br/>
CREATE VIEW majeurs AS SELECT ... FROM<br/>
eleves WHERE age &gt;= 18;. Ensuite,<br/>
SELECT * FROM majeurs renvoie le résultat<br/>
actualisé. Avantages : factoriser des<br/>
requêtes complexes, masquer certaines<br/>
colonnes (sécurité), simplifier l'écriture<br/>
des requêtes. La vue ne stocke pas les<br/>
données, elle stocke la requête.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une représentation graphique des relations<br/>
entre les tables</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une représentation graphique<br/>
s'appelle un <strong>schéma</strong> ou un diagramme<br/>
entité-association, pas une vue. La vue est<br/>
une notion logique (une requête nommée),<br/>
pas une représentation visuelle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un type particulier d'index pour accélérer<br/>
les recherches</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un index est une structure<br/>
auxiliaire de performance ; une vue est une<br/>
requête nommée. Ces deux notions sont<br/>
totalement distinctes, même si certains<br/>
SGBD permettent des « vues matérialisées »<br/>
qui s'apparentent à un index.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une copie figée des données à un instant<br/>
donné</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait une <strong>table</strong> (par<br/>
exemple créée via CREATE TABLE ... AS<br/>
SELECT ...). La vue, elle, ne contient pas<br/>
de données : elle contient une requête,<br/>
réévaluée à chaque interrogation pour<br/>
refléter l'état courant des tables source.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q34 : Lecture d'un schéma relationnel</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère le schéma relationnel suivant :</p>
<p>`<code><br/>
eleves(id_eleve, nom, prenom, id_classe#)<br/>
classes(id_classe, niveau, salle)<br/>
notes(id_eleve#, id_devoir#, note)<br/>
devoirs(id_devoir, matiere, date)<br/>
</code></p>
<p>Le #` désigne une clé étrangère. Quelle<br/>
affirmation est correcte ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Méthode pour lire un schéma relationnel : (1)<br/>
identifier la clé primaire de chaque table<br/>
(souvent soulignée ou notée en premier) ; (2)<br/>
repérer les clés étrangères (notées #,<br/>
soulignées en pointillés, ou en italique selon<br/>
la convention) ; (3) interpréter les<br/>
cardinalités. Ici, l'association notes est<br/>
une <strong>association n-aire</strong> typique, qui ne<br/>
peut pas se modéliser par une simple clé<br/>
étrangère ajoutée à une table existante.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La table eleves n'a pas de lien avec<br/>
classes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la colonne id_classe# dans<br/>
eleves est précisément une clé<br/>
étrangère qui pointe vers classes, ce<br/>
qui établit le lien « un élève appartient<br/>
à une classe ».</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On peut avoir plusieurs élèves avec le<br/>
même id_eleve</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : id_eleve est la clé primaire de<br/>
la table eleves, donc unique par<br/>
définition. Deux élèves différents ne<br/>
peuvent pas partager la même valeur de<br/>
id_eleve.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour ajouter une note dans notes, il<br/>
n'est pas nécessaire que l'élève existe<br/>
dans eleves</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la clé étrangère id_eleve# dans<br/>
notes impose que la valeur référence un<br/>
élève existant. Insérer une note pour un<br/>
élève inexistant viole l'intégrité<br/>
référentielle et le SGBD rejette<br/>
l'opération.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La table notes a une clé primaire<br/>
composite (id_eleve, id_devoir), et ses<br/>
deux composantes sont des clés étrangères<br/>
référençant respectivement eleves et<br/>
devoirs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est la lecture correcte<br/>
du schéma. La table notes représente une<br/>
association ternaire (un élève, un devoir,<br/>
une note). La clé primaire composite<br/>
garantit l'unicité (un élève ne peut avoir<br/>
qu'une note par devoir), et les clés<br/>
étrangères assurent l'intégrité<br/>
référentielle (on ne peut pas mettre une<br/>
note pour un élève ou un devoir<br/>
inexistants).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q35 : Injection SQL</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un programme construit la requête SQL suivante<br/>
en concaténant directement la chaîne<br/>
nom_saisi reçue de l'utilisateur :</p>
<p>`<code>python<br/>
requete = "SELECT * FROM users WHERE nom = '" + nom_saisi + "';"<br/>
</code></p>
<p>Si l'utilisateur saisit<br/>
' OR '1'='1`, que se passe-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'injection SQL reste, en 2026, l'une des<br/>
vulnérabilités les plus exploitées dans les<br/>
applications web. La parade est connue depuis<br/>
longtemps : ne <strong>jamais</strong> construire une<br/>
requête SQL par concaténation de chaînes<br/>
utilisateur, mais utiliser systématiquement<br/>
des <strong>requêtes préparées</strong> où les paramètres<br/>
sont passés séparément<br/>
(cursor.execute("... WHERE nom = ?", (nom_saisi,))).<br/>
Le SGBD échappe alors automatiquement les<br/>
caractères dangereux.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le SGBD détecte l'injection et rejette la<br/>
requête</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la requête est syntaxiquement<br/>
parfaitement valide. Le SGBD n'a aucun<br/>
moyen de détecter qu'elle vient d'une<br/>
concaténation dangereuse plutôt que d'une<br/>
intention légitime. C'est précisément ce<br/>
qui rend l'injection SQL si pernicieuse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Python lève une exception au moment de la<br/>
concaténation</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python concatène sans aucun<br/>
problème les chaînes, quel que soit leur<br/>
contenu. Aucune exception n'est levée.<br/>
C'est précisément le drame : tout se passe<br/>
silencieusement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La requête devient<br/>
SELECT * FROM users WHERE nom = '' OR '1'='1';,<br/>
ce qui sélectionne toutes les lignes<br/>
de la table : c'est une injection SQL</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la concaténation naïve fait<br/>
sortir la chaîne saisie de son rôle de<br/>
simple donnée et l'injecte dans la<br/>
structure SQL. La condition '1'='1'<br/>
étant toujours vraie, l'opérateur OR la<br/>
fait court-circuiter le filtre. C'est la<br/>
forme la plus simple d'injection SQL,<br/>
célèbre attaque qui a touché de nombreux<br/>
sites mal protégés. La parade standard :<br/>
utiliser des <strong>requêtes préparées</strong> avec<br/>
des paramètres liés<br/>
(cursor.execute(req, (nom_saisi,))).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La requête ne retourne aucune ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'inverse. La condition<br/>
'1'='1' étant toujours vraie, <strong>toutes</strong><br/>
les lignes de la table sont retournées,<br/>
y compris des données potentiellement<br/>
sensibles que l'utilisateur ne devrait<br/>
pas voir.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q36 : Trace d'un UPDATE ciblé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On part de la table comptes suivante :</p>
<p>| id | titulaire | solde |<br/>
|----|-----------|-------|<br/>
| 1  | Alice     | 1000  |<br/>
| 2  | Bob       | 500   |<br/>
| 3  | Chloé     | 2000  |</p>
<p>On exécute la requête suivante :</p>
<p>`<code>sql<br/>
UPDATE comptes<br/>
SET solde = solde * 1.05<br/>
WHERE solde &gt;= 1000;<br/>
</code>`</p>
<p>Quel est le contenu de la table après<br/>
exécution ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma général d'un UPDATE : (1) la clause<br/>
WHERE sélectionne les lignes affectées ; (2)<br/>
la clause SET indique comment modifier ces<br/>
lignes ; (3) le SGBD applique la modification<br/>
atomiquement (toutes les lignes en une seule<br/>
opération). Sans WHERE, <strong>toutes</strong> les lignes<br/>
sont modifiées, ce qui est rarement souhaité<br/>
et souvent catastrophique.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Bob est supprimé de la table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : UPDATE ne supprime jamais de<br/>
ligne, il ne fait que modifier des<br/>
valeurs. Pour supprimer une ligne, il<br/>
faudrait utiliser DELETE FROM comptes<br/>
WHERE solde &lt; 1000;.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toutes les lignes voient leur solde<br/>
multiplié par 1{,}05</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est ce qui se passerait si la<br/>
clause WHERE était absente. Avec<br/>
WHERE solde &gt;= 1000, seules les lignes<br/>
satisfaisant la condition sont<br/>
modifiées. Bob (500) ne fait pas partie<br/>
du lot.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Alice : 1050, Bob : 500 (inchangé),<br/>
Chloé : 2100</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la clause WHERE solde &gt;= 1000<br/>
sélectionne les lignes où le solde est<br/>
d'au moins 1000 (Alice et Chloé). Pour<br/>
chacune, on applique solde = solde * 1.05.<br/>
Alice passe de 1000 à 1050, Chloé de<br/>
2000 à 2100. Bob, dont le solde est<br/>
inférieur à 1000, n'est pas affecté.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La table reste inchangée car la clause<br/>
WHERE est trop restrictive</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Alice (1000) et Chloé (2000)<br/>
satisfont bien la condition solde &gt;= 1000,<br/>
donc leurs lignes sont modifiées. La<br/>
condition n'est pas trop restrictive : elle<br/>
est ciblée.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
