<?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</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 façon unique chaque ligne</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 obligatoirement être un nombre entier positif</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 <code>NULL</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une clé primaire ne peut <strong>jamais</strong> être<br/>
<code>NULL</code>, 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 <code>(eleve_id, cours_id)</code> 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é 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 référençant 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 <code>Commandes</code>, l'attribut <code>client_id</code> référence<br/>
la clé primaire de la table <code>Clients</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une clé dont la valeur ne peut jamais être modifiée ensuite</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 <code>eleves</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : éviter <code>SELECT *</code> 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><code>SELECT eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe <code>SELECT</code> requiert au minimum la<br/>
liste des colonnes (ou <code>*</code>) puis <code>FROM</code> pour la table.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>GET ALL FROM eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>GET</code> n'existe pas en SQL. La commande de<br/>
lecture est <code>SELECT</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>SELECT * FROM eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>*</code> est le joker qui désigne toutes<br/>
les colonnes. <code>FROM</code> indique la table source.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>READ eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>READ</code> n'est pas un mot-clé SQL. La lecture<br/>
se fait avec <code>SELECT</code>.</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/>
<code>eleves</code>, quelle requête utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une requête SQL classique a la forme :<br/>
<code>SELECT colonnes FROM table WHERE condition</code>. Les<br/>
conditions multiples se combinent avec <code>AND</code>, <code>OR</code>, <code>NOT</code>.</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>FILTER eleves WHERE age &gt;= 18</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>FILTER</code> n'est pas la syntaxe SQL standard.<br/>
On utilise <code>SELECT ... WHERE</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT * FROM eleves CONDITION age &gt;= 18</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>CONDITION</code> n'existe pas en SQL. C'est <code>WHERE</code><br/>
qui introduit la condition.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>SELECT * FROM eleves WHERE age &gt;= 18</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>WHERE</code> introduit la condition de<br/>
filtrage. La syntaxe est <code>WHERE condition</code>, où la<br/>
condition compare des valeurs avec les opérateurs<br/>
<code>=</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code> ou <code>&lt;&gt;</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT * FROM eleves IF age &gt;= 18</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>IF</code> n'est pas un mot-clé SQL pour le<br/>
filtrage. Le filtre se fait avec <code>WHERE</code>.</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 : <code>ORDER BY nom, prenom</code>.<br/>
Pour ordre décroissant : <code>ORDER BY nom DESC</code>. On peut<br/>
mélanger : <code>ORDER BY classe ASC, moyenne DESC</code>.</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>SELECT * FROM eleves ARRANGE BY nom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>ARRANGE BY</code> n'est pas du SQL valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>SELECT * FROM eleves ORDER BY nom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>ORDER BY</code> trie le résultat selon une<br/>
ou plusieurs colonnes. Par défaut, l'ordre est<br/>
ascendant (<code>ASC</code>). Pour un ordre descendant, ajouter<br/>
<code>DESC</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT * FROM eleves SORTED nom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>SORTED</code> n'existe pas en SQL.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT * FROM eleves SORT BY nom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>SORT BY</code> n'est pas une syntaxe SQL. Le tri<br/>
se fait avec <code>ORDER BY</code>.</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 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 restreignant les valeurs admissibles, 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 : <code>NOT NULL</code> (valeur<br/>
obligatoire), <code>UNIQUE</code> (pas de doublon), clé primaire,<br/>
clé étrangère, <code>CHECK</code> (condition arbitraire).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une copie de sauvegarde automatique et régulière des données</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 pour manipuler les données<br/>
d'une table sont : <code>SELECT</code> (lire), <code>INSERT</code> (ajouter),<br/>
<code>UPDATE</code> (modifier), <code>DELETE</code> (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><code>INSERT INTO eleves VALUES ('Alice', 17)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>INSERT INTO table VALUES (...)</code> est la<br/>
forme classique. On peut aussi préciser les colonnes :<br/>
<code>INSERT INTO eleves (nom, age) VALUES ('Alice', 17)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>CREATE INTO eleves VALUES ('Alice', 17)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>CREATE</code> est utilisé pour créer une table<br/>
(<code>CREATE TABLE</code>), pas pour insérer une ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>PUT INTO eleves VALUES ('Alice', 17)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>PUT</code> n'existe pas en SQL.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>ADD INTO eleves VALUES ('Alice', 17)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>ADD</code> 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 impérativement être un nombre 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 ne se décompose pas en plusieurs informations</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un attribut comme<br/>
<code>telephones = "06 12 ; 06 34"</code> 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 <code>UPDATE</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur ne peut jamais être nulle (<code>NULL</code> interdit)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport. L'absence de valeur est<br/>
gérée par <code>NULL</code> ou par la contrainte<br/>
<code>NOT NULL</code>.</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 <code>commandes</code> et <code>clients</code> en<br/>
reliant <code>commandes.client_id</code> à <code>clients.id</code>, quelle<br/>
syntaxe utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une jointure s'écrit <code>FROM table1 JOIN table2 ON condition</code>.<br/>
La condition relie en général la clé étrangère d'une table à<br/>
la clé primaire de l'autre ; les lignes sans correspondance<br/>
n'apparaissent pas dans le résultat.</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><code>SELECT * FROM commandes JOIN clients ON commandes.client_id = clients.id</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la condition <code>ON</code> relie la clé étrangère<br/>
<code>commandes.client_id</code> à la clé primaire <code>clients.id</code>. Seules<br/>
les commandes ayant un client correspondant apparaissent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT * FROM commandes JOIN clients</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans condition <code>ON</code>, rien n'indique quelle commande<br/>
va avec quel client. Chaque commande est associée à chaque<br/>
client, ce qui n'a aucun sens.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT * FROM commandes JOIN clients ON commandes.id = clients.id</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la condition relie la clé primaire des<br/>
commandes à celle des clients, alors que le lien est<br/>
porté par la clé étrangère <code>commandes.client_id</code>.<br/>
Chaque commande serait associée au client dont<br/>
l'identifiant coïncide par hasard avec son propre<br/>
numéro, ce qui n'a aucun sens.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT * FROM commandes WHERE commandes.client_id = clients.id</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la table <code>clients</code> n'est citée ni dans <code>FROM</code> ni dans<br/>
un <code>JOIN</code>. Le SGBD ne connaît donc pas <code>clients.id</code> et signale<br/>
une colonne inconnue.</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/>
<code>COUNT</code>, <code>SUM</code>, <code>AVG</code>, <code>MIN</code> et <code>MAX</code>. 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><code>SELECT MOYENNE(age) FROM eleves</code></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><code>SELECT (age) FROM eleves AVERAGE</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe <code>AVERAGE</code> après le <code>FROM</code> n'existe<br/>
pas. Les fonctions d'agrégation s'appliquent à<br/>
l'intérieur du <code>SELECT</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT MEAN(age) FROM eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction de moyenne en SQL standard<br/>
s'appelle <code>AVG</code>, pas <code>MEAN</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>SELECT AVG(age) FROM eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>AVG</code> (<em>average</em>) calcule la moyenne<br/>
arithmétique. Les fonctions d'agrégation principales<br/>
sont <code>COUNT</code>, <code>SUM</code>, <code>AVG</code>, <code>MIN</code>, <code>MAX</code>.</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 : <code>SELECT</code> … <code>FROM</code> … <code>WHERE</code> …<br/>
<code>ORDER BY</code> …. Le mot-clé <code>DESC</code> après <code>ORDER BY</code><br/>
indique un tri décroissant ; <code>ASC</code> (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><code>SELECT nom FROM eleves ORDER BY age DESC WHERE age &gt;= 18</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'ordre des clauses est imposé en SQL.<br/>
<code>WHERE</code> se place avant <code>ORDER BY</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>SELECT nom FROM eleves WHERE age &gt;= 18 ORDER BY age DESC</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>WHERE</code> filtre les lignes<br/>
(majeurs), puis <code>ORDER BY age DESC</code> les trie par<br/>
âge décroissant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT nom FROM eleves WHERE age &gt;= 18 ORDER BY age</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans le mot-clé <code>DESC</code>, le tri se fait<br/>
par défaut en ordre croissant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT nom FROM eleves WHERE age &gt;= 18 SORT age DESC</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la clause <code>SORT</code> n'existe pas en SQL<br/>
standard. Il faut utiliser <code>ORDER BY</code>.</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 <code>WHERE</code> sur les<br/>
<code>UPDATE</code> et <code>DELETE</code>. <strong>Sans elle, la modification s'applique à 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><code>MODIFY eleves SET note = note + 1 WHERE id = 42</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>MODIFY</code> n'est pas un mot-clé SQL standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>UPDATE eleves SET note = note + 1 WHERE id = 42</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>UPDATE</code> met à jour des lignes<br/>
existantes. La clause <code>SET</code> indique les modifications<br/>
et <code>WHERE</code> filtre les lignes affectées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>UPDATE eleves WHERE id = 42 SET note = note + 1</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ordre incorrect des clauses. La syntaxe<br/>
standard est <code>UPDATE table SET ... WHERE ...</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>CHANGE eleves SET note = note + 1 WHERE id = 42</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>CHANGE</code> 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 <code>eleves</code> (sans doublons), quelle requête<br/>
utiliser ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>DISTINCT</code> agit sur l'ensemble des colonnes<br/>
sélectionnées. Par exemple,<br/>
<code>SELECT DISTINCT nom, prenom FROM eleves</code> 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><code>SELECT DISTINCT classe FROM eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>DISTINCT</code> é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><code>SELECT classe DISTINCT FROM eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>DISTINCT</code> se place <strong>avant</strong> la liste des<br/>
colonnes, juste après <code>SELECT</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT UNIQUE classe FROM eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>UNIQUE</code> 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 <code>DISTINCT</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT classe FROM eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans <code>DISTINCT</code>, 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 <code>eleves</code> avec autant de colonnes <code>cours_1</code>, <code>cours_2</code>, <code>cours_3</code> 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 <code>eleve</code> 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 <code>eleves(id, nom)</code>, <code>cours(id, intitule)</code> et <code>inscriptions(eleve_id, cours_id)</code> 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 — Q18 : Suppression d'une ligne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que fait la requête <code>DELETE FROM eleves;</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Toujours utiliser <code>WHERE</code> avec <code>DELETE</code>, sauf intention<br/>
explicite de tout vider. Beaucoup de SGBD permettent<br/>
d'imposer une clause <code>WHERE</code> 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 <code>eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>DELETE</code> sans clause <code>WHERE</code> 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 <code>DROP TABLE eleves</code>.</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 <code>DROP TABLE</code> qui supprime la structure.<br/>
<code>DELETE FROM</code> 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 <code>WHERE</code>)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans <code>WHERE</code>, 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 la clé étrangère :<br/>
le SGBD refuse toute insertion ou modification qui ferait<br/>
pointer <code>client_id</code> vers un client inexistant, et refuse aussi<br/>
de supprimer un client encore cité par des commandes.</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'<code>id</code>) 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 <code>client_id</code> inexistant dans <code>clients</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la clé étrangère <code>client_id</code> doit<br/>
pointer vers une ligne existante de la table<br/>
<code>clients</code>. 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 : une valeur manquante concerne l'attribut lui-même,<br/>
pas l'intégrité référentielle. Cette dernière porte sur les<br/>
références d'une table vers une autre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier l'ensemble des commandes par leur date croissante</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 — Q22 : Détection d'une redondance</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une table <code>commandes(id, client_id, nom_client, prenom_client, produit, prix)</code><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 de la table est manifestement mal choisie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>id</code> 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 sont dupliquées à chaque commande</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est une <strong>redondance</strong><br/>
classique, source d'incohérences. Le nom et le prénom dépendent de<br/>
<code>client_id</code>, pas de l'<code>id</code> de commande. Il<br/>
faudrait les mettre dans une table <code>clients</code><br/>
séparée et conserver uniquement la clé<br/>
étrangère <code>client_id</code> dans <code>commandes</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le prix devrait être stocké dans une table <code>produits</code> séparée</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 <code>commandes</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La table contient trop de colonnes pour être performante</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 : Anomalie de suppression</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le lycée enregistre les inscriptions aux clubs dans une seule<br/>
table :</p>
<pre><code>| id_inscription | nom_eleve | club      | salle |
|----------------|-----------|-----------|-------|
| 1              | Amina     | Échecs    | B12   |
| 2              | Basile    | Théâtre   | A03   |
| 3              | Chloé     | Théâtre   | A03   |
| 4              | Dorian    | Robotique | C07   |</code></pre>
<p>Dorian quitte le club de robotique, et l'on exécute<br/>
<code>DELETE FROM inscriptions WHERE id_inscription = 4;</code>.<br/>
Quel défaut du schéma cette suppression révèle-t-elle ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La table mélange deux informations : les inscriptions et les<br/>
salles des clubs. On sépare le schéma en<br/>
<code>clubs(<em>id_club, nom, salle)</code> et<br/>
<code>inscriptions(</em>id_inscription, nom_eleve, id_club#)</code> : supprimer<br/>
une inscription ne fait alors plus rien perdre sur le club.</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 base ne sait plus que la robotique a lieu en salle C07</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la salle d'un club n'est enregistrée que dans<br/>
les lignes d'inscription. En supprimant la seule inscription au<br/>
club de robotique, on perd aussi cette information : c'est une<br/>
anomalie de suppression.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le SGBD refuse la suppression, la salle C07 étant encore utilisée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune clé étrangère ne relie cette table à une table<br/>
de salles. Rien n'empêche la suppression, qui est acceptée, et<br/>
c'est justement ce qui fait perdre l'information.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La requête supprime aussi les autres inscriptions de Dorian</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la condition <code>id_inscription = 4</code> désigne une seule<br/>
ligne, puisque <code>id_inscription</code> est la clé primaire. Aucune autre<br/>
ligne n'est touchée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun défaut : chaque club garde sa salle dans une autre ligne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est vrai pour le théâtre, présent dans deux lignes,<br/>
mais pas pour la robotique, qui n'apparaissait que dans la ligne<br/>
supprimée.</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>Si le SGBD ne gérait pas les accès concurrents, deux programmes<br/>
qui modifient en même temps le même compte bancaire pourraient<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 : une modification efface l'effet de l'autre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : si le programme A lit le solde ($1000$), puis<br/>
le programme B le lit aussi ($1000$), puis A ajoute $100$ et<br/>
écrit $1100$, puis B ajoute $50$ et écrit $1050$, le dépôt<br/>
de A 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 au moment de l'exécution</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 programmes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans gestion des accès concurrents, on obtient au<br/>
contraire des incohérences. La coordination des écritures<br/>
demande un peu de temps, mais rend les données fiables.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q26 : Structure ou contenu d'une base</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans la base de données d'un lycée, laquelle de ces opérations<br/>
modifie la <strong>structure</strong> de la base, et non son contenu ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La structure d'une base est l'ensemble de ses schémas<br/>
relationnels : relations, attributs, domaines, clés primaires et<br/>
étrangères. Le contenu, ce sont les lignes, que les requêtes<br/>
<code>INSERT</code>, <code>UPDATE</code> et <code>DELETE</code> font évoluer sans toucher à la<br/>
structure.</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>Inscrire un nouvel élève dans la relation <code>eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un <code>INSERT</code> ajoute une ligne, c'est-à-dire un nouvel<br/>
élément du contenu. Le schéma de la relation <code>eleves</code> reste le<br/>
même.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Changer la classe d'un élève qui a été réorienté</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un <code>UPDATE</code> modifie la valeur d'un attribut dans une<br/>
ligne existante. Les attributs de la relation et leurs domaines<br/>
ne changent pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Ajouter un attribut <code>email</code> à la relation <code>eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ajouter un attribut change le schéma relationnel<br/>
de <code>eleves</code>, donc la structure de la base. Toutes les lignes,<br/>
présentes et futures, sont concernées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Supprimer tous les élèves qui ont quitté le lycée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : même s'il retire beaucoup de lignes d'un coup, un<br/>
<code>DELETE</code> ne touche que le contenu. La relation garde les mêmes<br/>
attributs.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q27 : Compter après une jointure filtrée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On dispose des deux tables suivantes.<br/>
Table <code>eleves</code> :<br/>
<pre><code>| id | nom    | classe |
|----|--------|--------|
| 1  | Amina  | T1     |
| 2  | Basile | T2     |
| 3  | Chloé  | T1     |
| 4  | Dorian | T1     |</code></pre><br/>
Table <code>notes</code> :<br/>
<pre><code>| id | id_eleve | valeur |
|----|----------|--------|
| 10 | 1        | 14     |
| 11 | 1        | 10     |
| 12 | 2        | 16     |
| 13 | 3        | 9      |
| 14 | 1        | 15     |
| 15 | 3        | 12     |
| 16 | 4        | 7      |</code></pre><br/>
Que renvoie la requête suivante ?<br/>
<pre><code>SELECT COUNT(*)
FROM notes
JOIN eleves ON notes.id_eleve = eleves.id
WHERE eleves.classe = 'T1' AND notes.valeur &gt;= 10;</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La requête s'évalue en trois temps : la jointure apparie chaque<br/>
note à son élève, le <code>WHERE</code> ne garde que les lignes qui vérifient<br/>
les deux conditions, puis <code>COUNT(*)</code> compte les lignes restantes.</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$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $2$ est le nombre d’élèves concernés, Amina et Chloé.<br/>
La requête compte les lignes de la jointure, une par note : les<br/>
notes retenues d'un même élève comptent chacune.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$3$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le résultat avec <code>notes.valeur &gt; 10</code>. La<br/>
condition <code>&gt;=</code> retient aussi la note $10$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$4$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la jointure associe chaque note à son élève.<br/>
Parmi les six notes des élèves de T1, quatre valent au moins<br/>
$10$ : $14, 10, 15$ pour Amina, 12 pour Chloé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$6$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $6$ est le nombre de notes des élèves de T1. La seconde<br/>
condition du <code>WHERE</code> écarte encore les notes $9, 7$.</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 <code>eleves</code> suivante :<br/>
<pre><code>| id | nom    | classe | moyenne |
|----|--------|--------|---------|
| 1  | Alice  | 1A     | 14.5    |
| 2  | Bob    | 1B     | 9.0     |
| 3  | Chloé  | 1A     | 16.0    |
| 4  | David  | 1B     | 13.0    |
| 5  | Émma   | 1A     | 11.5    |</code></pre><br/>
Que renvoie la requête suivante ?<br/>
<pre><code>SELECT nom, moyenne
FROM eleves
WHERE classe = '1A' AND moyenne &gt;= 12
ORDER BY moyenne DESC;</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Méthode systématique pour évaluer une requête<br/>
SQL : (1) appliquer le filtre <code>WHERE</code> pour ne<br/>
conserver que les lignes pertinentes ; (2)<br/>
projeter sur les colonnes du <code>SELECT</code> ; (3)<br/>
trier selon <code>ORDER BY</code> 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 <code>WHERE</code>.<br/>
Sans filtre, on aurait bien toutes les<br/>
lignes, mais ici la requête restreint aux<br/>
élèves de <code>1A</code> avec une moyenne d'au moins<br/>
$12$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trois lignes, dans l'ordre de la table : <code>('Alice', 14.5)</code>, <code>('Chloé', 16.0)</code>, <code>('Émma', 11.5)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'ordre n'est pas celui de la table<br/>
mais celui de <code>ORDER BY moyenne DESC</code>, et le<br/>
filtre <code>moyenne &gt;= 12</code> doit être vérifié<br/>
ligne par ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Deux lignes : <code>('Chloé', 16.0)</code> puis <code>('Alice', 14.5)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse. Étape 1, le filtre<br/>
<code>WHERE classe = '1A' AND moyenne &gt;= 12</code><br/>
retient les élèves de la classe <code>1A</code> avec<br/>
une moyenne d'au moins $12$ : Alice ($14{,}5$) et Chloé ($16$).<br/>
Émma est en <code>1A</code> mais sa moyenne ($11{,}5$) ne satisfait pas la deuxième condition. Étape 2, on ne garde<br/>
que les colonnes <code>nom</code> et <code>moyenne</code>. Étape 3,<br/>
on trie par <code>moyenne DESC</code> : Chloé d'abord, puis Alice.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une seule ligne : <code>('Chloé', 16.0)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Alice satisfait aussi les deux<br/>
conditions (classe <code>1A</code> et moyenne d'au moins<br/>
$12$). Cette ligne doit donc apparaître dans le<br/>
résultat, après la première 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 <code>clients</code> :</p>
<pre><code>| id | nom    |
|----|--------|
| 1  | Alice  |
| 2  | Bob    |
| 3  | Chloé  |</code></pre>
<p>Table <code>commandes</code> :</p>
<pre><code>| id | client_id | produit  |
|----|-----------|----------|
| 10 | 1         | Livre    |
| 11 | 2         | Cahier   |
| 12 | 1         | Stylo    |</code></pre>
<p>Combien de lignes renvoie la requête suivante ?</p>
<pre><code>SELECT c.nom, cmd.produit
FROM clients c
JOIN commandes cmd ON c.id = cmd.client_id;</code></pre>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une jointure <code>JOIN ... ON</code> produit une<br/>
ligne par paire qui vérifie la<br/>
condition. Un client sans commande,<br/>
comme Chloé, disparaît du résultat ;<br/>
un client à plusieurs commandes, comme<br/>
Alice, y figure plusieurs fois.</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 <code>'Livre'</code> et avec <code>'Stylo'</code>). 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 (<code>JOIN</code>,<br/>
synonyme de <code>INNER JOIN</code>) ne garde que les<br/>
paires <code>(client, commande)</code> où la condition<br/>
<code>c.id = cmd.client_id</code> 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/>
<code>('Alice', 'Livre')</code>, <code>('Bob', 'Cahier')</code>,<br/>
<code>('Alice', 'Stylo')</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>9 lignes (chaque client apparié à chaque commande)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le résultat sans<br/>
condition de jointure. La condition<br/>
<code>ON c.id = cmd.client_id</code> ne garde que<br/>
les paires cohérentes, soit trois<br/>
lignes ici.</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/>
et chacune est associée à un seul<br/>
client. Chloé, qui n'a aucune commande,<br/>
n'apporte aucune ligne au résultat.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q32 : Lire un résultat de requête depuis Python</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La table <code>eleves(id, nom, moyenne)</code> de la base <code>lycee.db</code> contient<br/>
quatre lignes : Basile ($13.5$), Amina ($15.0$), Chloé ($11.0$) et<br/>
Dorian ($12.0$). On exécute :</p>
<pre><code>import sqlite3

connexion = sqlite3.connect("lycee.db")
curseur = connexion.cursor()
curseur.execute("SELECT nom, moyenne FROM eleves WHERE moyenne &gt; 12 ORDER BY nom")
resultats = curseur.fetchall()
print(resultats[0])
connexion.close()</code></pre>
<p>Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Depuis Python, <code>execute</code> envoie la requête SQL au SGBD, et<br/>
<code>fetchall</code> récupère le résultat sous forme de liste de p-uplets,<br/>
un par ligne. On traite ensuite ces données avec les outils<br/>
habituels : indexation, boucles, tests.</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>Amina</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque ligne du résultat est un p-uplet qui contient<br/>
toutes les colonnes demandées dans le <code>SELECT</code>, ici <code>nom</code> et<br/>
<code>moyenne</code>. <code>resultats[0]</code> est ce p-uplet entier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>('Basile', 13.5)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Basile est la première ligne de la table, mais<br/>
<code>ORDER BY nom</code> range le résultat par ordre alphabétique. Amina<br/>
passe devant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>('Amina', 15.0)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>fetchall</code> renvoie la liste des lignes du<br/>
résultat, chacune sous forme de p-uplet. Amina et Basile ont une<br/>
moyenne supérieure à $12$, et Amina vient en premier dans<br/>
l'ordre alphabétique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[('Amina', 15.0), ('Basile', 13.5)]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le contenu de <code>resultats</code> tout entier.<br/>
L'indexation <code>resultats[0]</code> n'en extrait que le premier<br/>
élément.</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>
<pre><code>eleves(*id_eleve, nom, prenom, id_classe#)
classes(*id_classe, niveau, salle)
notes(*id_eleve#, *id_devoir#, note)
devoirs(*id_devoir, matiere, date)</code></pre>
<p>Le <code>*</code> marque les attributs qui composent la<br/>
clé primaire de chaque table (souligné dans<br/>
la notation usuelle) et le <code>#</code> désigne une<br/>
clé étrangère. Quelle affirmation est<br/>
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 <code>#</code>,<br/>
soulignées en pointillés, ou en italique selon<br/>
la convention) ; (3) interpréter les<br/>
cardinalités. Ici, l'association <code>notes</code> est<br/>
une <strong>association plusieurs-à-plusieurs</strong><br/>
typique, qui ne peut pas se modéliser par une<br/>
simple clé étrangère ajoutée à une table<br/>
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 <code>eleves</code> n'a pas de lien avec<br/>
<code>classes</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la colonne <code>id_classe#</code> dans<br/>
<code>eleves</code> est précisément une clé<br/>
étrangère qui pointe vers <code>classes</code>, 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 <code>id_eleve</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>id_eleve</code> est la clé primaire de<br/>
la table <code>eleves</code>, donc unique par<br/>
définition. Deux élèves différents ne<br/>
peuvent pas partager la même valeur de<br/>
<code>id_eleve</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour ajouter une note dans <code>notes</code>, il<br/>
n'est pas nécessaire que l'élève existe<br/>
dans <code>eleves</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la clé étrangère <code>id_eleve#</code> dans<br/>
<code>notes</code> 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 clé primaire de <code>notes</code> est composite,<br/>
formée de deux clés étrangères</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la clé <code>(id_eleve,<br/>
id_devoir)</code> référence respectivement<br/>
<code>eleves</code> et <code>devoirs</code>. C'est la lecture<br/>
correcte du schéma. La table <code>notes</code> représente une<br/>
association binaire porteuse d'un attribut<br/>
(elle relie un élève et un devoir, et<br/>
porte la 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/>
<code>nom_saisi</code> reçue de l'utilisateur :</p>
<pre><code>requete = "SELECT * FROM users WHERE nom = '" + nom_saisi + "';"</code></pre>
<p>Si l'utilisateur saisit<br/>
<code>' OR '1'='1</code>, 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/>
(<code>cursor.execute("... WHERE nom = ?", (nom_saisi,))</code>).<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>Toutes les lignes de la table sont<br/>
renvoyées : c'est une injection SQL</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la requête devient<br/>
<code>SELECT * FROM users WHERE nom = '' OR '1'='1';</code>.<br/>
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 <code>'1'='1'</code><br/>
étant toujours vraie, l'opérateur <code>OR</code> 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/>
(<code>cursor.execute(req, (nom_saisi,))</code>).</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/>
<code>'1'='1'</code> é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 <code>comptes</code> suivante :<br/>
<pre><code>| id | titulaire | solde |
|----|-----------|-------|
| 1  | Alice     | 1000  |
| 2  | Bob       | 500   |
| 3  | Chloé     | 2000  |</code></pre><br/>
On exécute la requête suivante :<br/>
<pre><code>UPDATE comptes
SET solde = solde * 1.05
WHERE solde &gt;= 1000;</code></pre><br/>
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 <code>UPDATE</code> : (1) la clause<br/>
<code>WHERE</code> sélectionne les lignes affectées ; (2)<br/>
la clause <code>SET</code> indique comment modifier ces<br/>
lignes ; (3) le SGBD applique la modification<br/>
atomiquement (toutes les lignes en une seule<br/>
opération). Sans <code>WHERE</code>, <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 : <code>UPDATE</code> ne supprime jamais de<br/>
ligne, il ne fait que modifier des<br/>
valeurs. Pour supprimer une ligne, il<br/>
faudrait utiliser <code>DELETE FROM comptes<br/>
WHERE solde &lt; 1000;</code>.</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 <code>WHERE</code> était absente. Avec<br/>
<code>WHERE solde &gt;= 1000</code>, 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é), Chloé : $2100$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la clause <code>WHERE solde &gt;= 1000</code><br/>
sélectionne les lignes où le solde est<br/>
d'au moins $1000$ (Alice et Chloé). Pour<br/>
chacune, on applique <code>solde = solde * 1.05</code>.<br/>
Alice passe de $1000$ à $1050$, Chloé de $2000$ à $2100$. Bob, dont le solde est 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/>
<code>WHERE</code> est trop restrictive</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Alice ($1000$) et Chloé ($2000$)<br/>
satisfait bien la condition <code>solde &gt;= 1000</code>,<br/>
donc la ligne est modifiée. La<br/>
condition n'est pas trop restrictive : elle<br/>
est ciblée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q37 : Rôle de la clause ON</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans la requête<br/>
<code>SELECT * FROM livres JOIN auteurs ON livres.id_auteur = auteurs.id</code>,<br/>
à quoi sert la clause <code>ON</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une jointure combine deux tables ligne à ligne. La<br/>
clause <code>ON</code> donne la règle d'appariement, presque<br/>
toujours l'égalité entre la clé étrangère d'une<br/>
table et la clé primaire de l'autre. Sans elle, le<br/>
SGBD ne saurait pas quelle ligne d'<code>auteurs</code><br/>
accompagne chaque livre.</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>À indiquer la condition qui apparie une ligne de <code>livres</code> à une ligne d'<code>auteurs</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Chaque livre est associé à l'auteur dont<br/>
l'identifiant est égal à sa clé étrangère<br/>
<code>id_auteur</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À trier les lignes du résultat selon les valeurs de la colonne <code>auteurs.id</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le tri s'obtient avec <code>ORDER BY</code> ; <code>ON</code> ne<br/>
change pas l'ordre des lignes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À choisir les colonnes des deux tables qui apparaissent dans le résultat</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce choix revient à <code>SELECT</code> ; ici l'étoile<br/>
affiche toutes les colonnes des deux tables.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À renommer la table <code>auteurs</code> en <code>livres</code> le temps de la requête</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Renommer une table se fait avec <code>AS</code> ; <code>ON</code><br/>
compare des colonnes, il ne renomme rien.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q38 : Écrire une jointure villes et pays</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La base contient <code>villes(id, nom, id_pays)</code> et<br/>
<code>pays(id, nom)</code>, où <code>id_pays</code> est une clé étrangère<br/>
vers <code>pays</code>. Quelle requête affiche le nom de chaque<br/>
ville suivi du nom de son pays ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour relier deux tables, on cherche la clé étrangère<br/>
de l'une et la clé primaire de l'autre :<br/>
<code>villes.id_pays</code> désigne <code>pays.id</code>. La condition de<br/>
jointure compare exactement ces deux colonnes.</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><code>SELECT villes.nom, pays.nom FROM villes JOIN pays ON villes.id_pays = pays.id</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La clé étrangère <code>id_pays</code> est comparée à la clé<br/>
primaire <code>id</code> de la table <code>pays</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT villes.nom, pays.nom FROM villes JOIN pays ON villes.id = pays.id</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette condition apparie une ville et un pays qui<br/>
ont par hasard le même numéro d'identifiant, ce<br/>
qui n'a aucun sens.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT villes.nom, pays.nom FROM villes WHERE villes.id_pays = pays.id</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La table <code>pays</code> n'est pas dans la clause <code>FROM</code> :<br/>
le SGBD signale une colonne inconnue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT villes.nom, pays.nom FROM villes JOIN pays ON villes.nom = pays.nom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Comparer le nom d'une ville au nom d'un pays<br/>
n'apparie rien, sauf homonymie accidentelle.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q39 : Un auteur absent du résultat</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Table <code>auteurs</code> :</p>
<pre><code>| id | nom     |
|----|---------|
| 1  | Colette |
| 2  | Camus   |
| 3  | Duras   |</code></pre>
<p>Table <code>livres</code> :</p>
<pre><code>| id | titre      | id_auteur |
|----|------------|-----------|
| 10 | Chéri      | 1         |
| 11 | La Peste   | 2         |
| 12 | Sido       | 1         |
| 13 | L'Étranger | 2         |
| 14 | Gigi       | 1         |</code></pre>
<p>On exécute :</p>
<pre><code>SELECT auteurs.nom, livres.titre
FROM auteurs JOIN livres ON auteurs.id = livres.id_auteur;</code></pre>
<p>Pourquoi le nom « Duras » n'apparaît-il pas dans le<br/>
résultat ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le résultat compte cinq lignes, une par livre,<br/>
chacune avec le nom de son auteur. Un auteur sans<br/>
livre ne forme aucune paire et disparaît : c'est le<br/>
comportement de la jointure interne, la seule au<br/>
programme.</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>Parce qu'aucun livre n'a <code>id_auteur</code> égal à $3$ : la jointure ne garde que les paires appariées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une jointure produit une ligne par couple<br/>
(auteur, livre) vérifiant la condition ; Duras<br/>
n'entre dans aucun couple.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que la table <code>auteurs</code> est citée en premier dans <code>FROM</code>, ce qui l'exclut du résultat</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'ordre des tables dans la jointure ne retire<br/>
aucune ligne ; Colette et Camus, de la même<br/>
table, apparaissent bien.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que le SGBD n'affiche que les deux premiers auteurs de la table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Rien ne limite le nombre d'auteurs ; Colette et<br/>
Camus figurent parce qu'ils ont des livres, pas<br/>
parce qu'ils sont en tête.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que la requête contient une erreur et ne renvoie que des lignes partielles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La requête est correcte et renvoie cinq lignes<br/>
complètes, une par livre.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q40 : Noms courts dans une jointure</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que désignent <code>e</code> et <code>c</code> dans la requête suivante ?</p>
<pre><code>SELECT e.nom, c.libelle
FROM eleves AS e
JOIN clubs AS c ON e.id_club = c.id;</code></pre>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>eleves AS e</code> déclare un alias. Partout ailleurs<br/>
dans la requête, <code>e.nom</code> signifie <code>eleves.nom</code>. Le<br/>
mot <code>AS</code> est facultatif : <code>FROM eleves e</code> a le même<br/>
effet.</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>Des alias : des noms courts donnés aux tables <code>eleves</code> et <code>clubs</code> le temps de la requête</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ils allègent l'écriture des colonnes et lèvent<br/>
toute ambiguïté quand deux tables ont une colonne<br/>
de même nom.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Deux colonnes de la table <code>eleves</code>, qui contiennent respectivement le nom et le libellé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>nom</code> et <code>libelle</code> sont les colonnes ; <code>e</code> et <code>c</code><br/>
précèdent le point et désignent des tables.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Deux nouvelles tables, créées dans la base au moment où la requête est exécutée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>AS</code> n'écrit rien dans la base ; les noms courts<br/>
disparaissent dès la fin de la requête.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'ordre de tri du résultat : d'abord selon les élèves (<code>e</code>), puis selon les clubs (<code>c</code>)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun <code>ORDER BY</code> n'est présent ; <code>e</code> et <code>c</code> ne<br/>
disent rien de l'ordre des lignes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q41 : Jointure puis filtre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Avec <code>livres(id, titre, annee, id_auteur)</code> et<br/>
<code>auteurs(id, nom)</code>, quelle requête renvoie les<br/>
titres des livres écrits par Colette ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Deux étapes : relier chaque livre à son auteur par<br/>
la clé étrangère, puis filtrer sur le nom. Le filtre<br/>
va dans <code>WHERE</code>, la règle d'appariement dans <code>ON</code>.</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><code>SELECT livres.titre FROM livres JOIN auteurs ON livres.id_auteur = auteurs.id WHERE auteurs.nom = 'Colette'</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La jointure attache l'auteur à chaque livre, puis<br/>
<code>WHERE</code> ne garde que les lignes dont l'auteur<br/>
s'appelle Colette.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT livres.titre FROM livres JOIN auteurs ON livres.id = auteurs.id WHERE auteurs.nom = 'Colette'</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La condition de jointure compare deux clés<br/>
primaires sans rapport : aucun livre n'est relié<br/>
à son auteur, et le résultat est faux sans<br/>
message d'erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT livres.titre FROM livres JOIN auteurs ON livres.id_auteur = auteurs.id WHERE livres.id_auteur = 'Colette'</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La jointure est bonne, mais <code>id_auteur</code> contient un<br/>
numéro, jamais un nom : le filtre ne garde aucune<br/>
ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>SELECT livres.titre FROM livres JOIN auteurs ON auteurs.nom = 'Colette'</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La condition de jointure ne relie pas les deux<br/>
tables : chaque livre est apparié à Colette,<br/>
qu'il soit d'elle ou non, et tous les titres<br/>
sortent.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q42 : Première ligne d'une jointure triée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Table <code>equipes</code> :</p>
<pre><code>| id | nom     |
|----|---------|
| 1  | Lions   |
| 2  | Aigles  |
| 3  | Requins |</code></pre>
<p>Table <code>joueurs</code> :</p>
<pre><code>| id | nom  | id_equipe | buts |
|----|------|-----------|------|
| 1  | Sami | 2         | 4    |
| 2  | Lou  | 1         | 7    |
| 3  | Inès | 3         | 2    |
| 4  | Teo  | 2         | 9    |
| 5  | Maya | 1         | 5    |</code></pre>
<pre><code>SELECT joueurs.nom, equipes.nom
FROM joueurs JOIN equipes ON joueurs.id_equipe = equipes.id
ORDER BY joueurs.buts DESC;</code></pre>
<p>Quelle est la première ligne du résultat ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La jointure remplace chaque <code>id_equipe</code> par le nom<br/>
de l'équipe correspondante ; le tri décroissant sur<br/>
<code>buts</code> place Teo ($9$) devant Lou ($7$), Maya ($5$),<br/>
Sami ($4$) et Inès ($2$).</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><code>Teo | Aigles</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Teo a le plus de buts ($9$) et son équipe,<br/>
d'identifiant $2$, est Aigles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Lou | Lions</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Lou vient en deuxième position avec $7$ buts.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Teo | Lions</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Teo joue dans l'équipe $2$, Aigles ; Lions porte<br/>
l'identifiant $1$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Inès | Requins</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Inès, avec $2$ buts, termine dernière du<br/>
classement décroissant.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q43 : Jointure sur trois tables</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Schéma : <code>eleves(id, nom)</code>, <code>activites(id, libelle)</code><br/>
et <code>inscriptions(id_eleve, id_activite)</code>. Quelle<br/>
requête affiche le nom de chaque élève avec le<br/>
libellé de chaque activité où il est inscrit ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>inscriptions</code> est une table de liaison : elle ne<br/>
contient que des clés étrangères. Il faut deux<br/>
jointures en chaîne, chacune reliant une clé<br/>
étrangère à la clé primaire visée.</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[<pre><code>SELECT eleves.nom, activites.libelle
FROM eleves
JOIN inscriptions ON eleves.id = inscriptions.id_eleve
JOIN activites ON inscriptions.id_activite = activites.id;</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Deux jointures en chaîne : l'élève est relié à<br/>
ses inscriptions, chaque inscription à son<br/>
activité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>SELECT eleves.nom, activites.libelle
FROM eleves
JOIN inscriptions ON eleves.id = inscriptions.id_activite
JOIN activites ON inscriptions.id_eleve = activites.id;</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les clés sont croisées : un élève est apparié<br/>
aux inscriptions dont le numéro d'activité vaut<br/>
son propre numéro. Le résultat est faux sans<br/>
aucun message d'erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>SELECT eleves.nom, activites.libelle
FROM eleves
JOIN activites ON eleves.id = activites.id;</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La table <code>inscriptions</code> est oubliée : on apparie<br/>
un élève à l'activité qui porte le même numéro,<br/>
sans rapport avec ses inscriptions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>SELECT eleves.nom, activites.libelle
FROM eleves, inscriptions, activites;</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans condition d'appariement, chaque élève est<br/>
associé à chaque inscription et à chaque<br/>
activité : le résultat contient toutes les<br/>
combinaisons.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q44 : Quand une jointure est nécessaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Base : <code>livres(id, titre, annee, id_auteur)</code> et<br/>
<code>auteurs(id, nom, pays)</code>. Quelle demande exige une<br/>
jointure ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une jointure sert quand les informations demandées,<br/>
ou les critères de filtrage, sont répartis sur<br/>
plusieurs tables. Si tout se trouve dans une seule<br/>
table, un <code>SELECT</code> simple 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="0" format="html">
    <text><![CDATA[<p>Les titres des livres parus après l'année $2000$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Titre et année sont dans la seule table<br/>
<code>livres</code> : un <code>WHERE annee &gt; 2000</code> suffit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les noms des auteurs dont le pays est la France</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La table <code>auteurs</code> contient le nom et le pays :<br/>
aucune autre table n'est nécessaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les titres des livres d'un auteur irlandais</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le titre est dans <code>livres</code> et le pays dans<br/>
<code>auteurs</code> : il faut relier les deux par<br/>
<code>id_auteur</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre de livres parus pendant l'année $1947$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>COUNT(*)</code> sur <code>livres</code> avec <code>WHERE annee = 1947</code><br/>
répond sans toucher à <code>auteurs</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q45 : Persistance des données</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On dit qu'un SGBD assure la <strong>persistance</strong> des données. Que<br/>
signifie cette propriété ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La persistance est l'un des services fondamentaux d'un SGBD : ce<br/>
qui a été validé est conservé durablement, quels que soient les<br/>
arrêts ou les pannes de courant ultérieurs.</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>Les données survivent à l'arrêt du programme et de la machine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les données sont écrites sur un support durable<br/>
et retrouvées intactes au redémarrage, contrairement aux<br/>
variables d'un programme, qui disparaissent avec lui.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les données sont gardées en mémoire vive pour être lues plus rapidement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la mémoire vive s'efface à l'extinction. La persistance<br/>
repose justement sur l'écriture sur un support durable, le cache<br/>
en mémoire n'étant qu'une accélération.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les données ne peuvent plus être modifiées une fois insérées dans la base</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une base vit, on y insère, modifie et supprime des<br/>
lignes. La persistance garantit que l'état courant survit aux<br/>
arrêts, pas qu'il est figé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les données sont recopiées automatiquement sur un second site distant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la réplication est une mesure de sécurité<br/>
supplémentaire, pas la définition de la persistance, qui<br/>
concerne d'abord la conservation locale sur disque.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q46 : Droits d'accès à une table</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans la base d'un lycée, le compte utilisé par l'application<br/>
d'affichage des emplois du temps doit pouvoir lire la table <code>cours</code><br/>
mais jamais la modifier. Quel mécanisme du SGBD répond à ce<br/>
besoin ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La sécurisation des accès est un service du SGBD : chaque compte<br/>
reçoit des droits précis, lecture seule pour une application<br/>
d'affichage, écriture pour la gestion, administration pour<br/>
quelques personnes.</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>Des droits d'accès limités à <code>SELECT</code> pour ce compte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le SGBD associe à chaque compte des droits par<br/>
table et par opération. Une requête de modification émise par<br/>
ce compte est refusée avant même d'être exécutée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le chiffrement de la table <code>cours</code>, illisible sans la clé de déchiffrement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chiffrer la table empêcherait aussi la lecture, qui est<br/>
précisément ce que l'application doit pouvoir faire. Le besoin<br/>
porte sur les opérations autorisées, pas sur la confidentialité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La clé primaire de la table <code>cours</code>, qui interdit toute modification des lignes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une clé primaire garantit l'unicité des lignes, elle ne<br/>
limite en rien les opérations permises à un compte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une contrainte d'intégrité qui rejette toute requête <code>UPDATE</code> sur la table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les contraintes d'intégrité portent sur la validité des<br/>
données, pas sur l'identité de celui qui les modifie. C'est la<br/>
gestion des droits qui distingue les comptes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q47 : Deux réservations simultanées</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Deux clients tentent au même instant de réserver la dernière place<br/>
d'un spectacle. Comment le SGBD évite-t-il de vendre deux fois la<br/>
même place ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sans gestion des accès concurrents, deux lectures simultanées de<br/>
« place libre » conduiraient à deux ventes. Le SGBD sérialise les<br/>
opérations conflictuelles pour que la base reste cohérente.</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>Il les traite l'une après l'autre, et la seconde trouve la place déjà prise</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la gestion des accès concurrents ordonne les<br/>
opérations comme si elles avaient été faites l'une après<br/>
l'autre. Le second client reçoit un refus cohérent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il accepte les deux réservations et signale le conflit à l'administrateur du site</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : accepter les deux, c'est précisément l'incohérence à<br/>
éviter. Le SGBD l'empêche avant qu'elle ne soit écrite, il ne se<br/>
contente pas de la signaler.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il refuse toute réservation tant que plusieurs clients sont connectés en même temps</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : bloquer tout le monde rendrait le service inutilisable.<br/>
Le SGBD n'arbitre que les opérations qui touchent les mêmes<br/>
données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il attribue la place au client dont la connexion au serveur est la plus rapide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la vitesse de connexion n'intervient pas. Le SGBD<br/>
garantit seulement qu'une des deux opérations est entièrement<br/>
traitée avant que l'autre ne lise l'état de la place.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q48 : Parade à l'injection SQL</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un programme construit ses requêtes à partir de valeurs saisies<br/>
par l'utilisateur. Quelle pratique le protège contre l'injection<br/>
SQL ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'injection SQL vient de la concaténation de texte saisi dans une<br/>
requête. La parade consiste à ne jamais mélanger les deux : la<br/>
requête est écrite avec des emplacements, et les valeurs sont<br/>
fournies à part.</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>Des requêtes paramétrées, les valeurs étant transmises à part</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : avec une requête paramétrée, la structure de la<br/>
requête est fixée avant que les valeurs n'y soient insérées.<br/>
Une saisie contenant <code>' OR 1=1</code> reste une simple chaîne de<br/>
caractères comparée telle quelle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le masquage des messages d'erreur renvoyés par le SGBD à l'utilisateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cacher les erreurs complique le travail de l'attaquant<br/>
mais n'empêche pas l'injection. Une requête détournée s'exécute<br/>
toujours, en silence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La limitation de la longueur des champs du formulaire à vingt caractères</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>' OR 1=1 --</code> tient en moins de vingt caractères. La<br/>
limitation gêne à peine l'attaque et ne traite pas sa cause, le<br/>
mélange entre code SQL et données.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le chiffrement de l'ensemble du contenu de la base de données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le chiffrement protège les données volées ou lues sur<br/>
le disque. Une requête injectée est exécutée par le SGBD<br/>
lui-même, qui déchiffre normalement ce qu'il renvoie.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q49 : Les sauvegardes d'une base de données</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi un système de gestion de bases de données sauvegarde-t-il<br/>
régulièrement les données qu'il héberge ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Parmi les services d'un SGBD figure la sécurité des données au<br/>
sens de leur conservation : la sauvegarde en est l'outil.</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 restaurer les données après une panne ou une erreur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un disque qui lâche, une requête de suppression<br/>
malheureuse ou un piratage détruisent des données ; seule une<br/>
copie récente permet de les retrouver.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour accélérer les requêtes les plus fréquentes du site</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la vitesse relève des index et de la mémoire cache, pas<br/>
des sauvegardes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour supprimer automatiquement les lignes en double</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les doublons se traitent par les contraintes<br/>
d'intégrité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour remplacer la gestion des droits d'accès des utilisateurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sauvegarde et droits d'accès sont deux garanties<br/>
distinctes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Bases de données et SQL — Q50 : Le compte utilisé par une application de consultation</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un site affiche les horaires d'une bibliothèque depuis une base de<br/>
données, sans jamais les modifier. Avec quel compte doit-il se<br/>
connecter à la base ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les droits d'accès s'attribuent selon le besoin réel : lire quand<br/>
il suffit de lire.</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 compte limité à la lecture, pour qu'une faille ne modifie rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : donner le moins de droits possible limite les<br/>
dégâts d'une attaque ; un compte en lecture seule ne peut ni<br/>
effacer ni altérer les horaires.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le compte administrateur, pour n'essuyer aucun refus d'accès</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une injection réussie disposerait alors de tous les<br/>
droits, suppression comprise.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun compte, les horaires étant des données publiques de toute façon</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le SGBD exige une identification pour tout accès, même<br/>
en lecture.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un compte distinct pour chaque visiteur, créé à la volée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les visiteurs ne se connectent pas à la base, c'est le<br/>
site qui le fait.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
