Le carnet
Examen blanc · TAD

Quiz blanc

Conditions réelles : 20 questions à travers les 6 chapitres. Calque le format du partiel.

~ 45 min 20 questions Tous les CMs
📋 Mode d'emploi
Réponds à toutes les questions sans regarder le cours. À la fin, refais les chapitres concernés par tes erreurs. Le score t'indique ton niveau de prêt.

✎ Examen blanc · TAD complet

0 / 20
1.Que peut faire un utilisateur juste après CREATE USER … IDENTIFIED BY … ?
  • Créer ses propres tables tout de suite
  • Se connecter, mais sans privilèges objet
  • Rien — il n'a aucun rôle ni privilège
  • Devenir DBA automatiquement
À la création, un user n'a aucun rôle — pas même CREATE SESSION. Il faut au minimum lui donner CONNECT.
2.Méthode de rafraîchissement par défaut d'une vue matérialisée ?
  • FAST
  • FORCE
  • COMPLETE
  • ON COMMIT
FORCE = essaie FAST sinon COMPLETE.
3.Une table contient une colonne statut avec 4 valeurs distinctes pour 2 millions de lignes, peu d'inserts. Quel index ?
  • B-tree
  • B-tree inversé
  • Bitmap
  • Index par fonction
Faible sélectivité (4/2M) + peu d'updates ⇒ bitmap.
4.Après avoir créé un cluster, que doit-on faire avant d'utiliser les tables ?
  • Lancer ANALYZE CLUSTER
  • Drop le tablespace par défaut
  • Forcer un COMMIT
  • Créer l'index sur le cluster
Sans CREATE INDEX ON CLUSTER, aucune opération possible sur les tables clustérisées.
5.Que signifie ACID ?
  • Atomicité · Cohérence · Indexation · Durabilité
  • Authentification · Confidentialité · Intégrité · Disponibilité
  • Atomicité · Cohérence · Isolation · Durabilité
  • Asynchronie · Cohérence · Indépendance · Décentralisation
ACID = Atomicité, Cohérence, Isolation, Durabilité.
6.Face à un interblocage T1 ↔ T2, Oracle :
  • Attend qu'un timeout expire
  • Détecte et annule une opération d'une transaction
  • Crash le serveur
  • Annule les deux transactions
Oracle annule une seule opération pour casser l'étreinte.
7.OLTP signifie :
  • Open Lightweight Transaction Protocol
  • Optimized Locking for Transaction Processing
  • Online Transaction Processing
  • Object-Level Transaction Pattern
Architecture pour transactions temps réel.
8.Une fragmentation horizontale correspond à quel opérateur algébrique ?
  • Projection
  • Jointure
  • Sélection
  • Différence
Sous-ensemble de lignes = sélection (σ).
9.Pour recomposer une fragmentation verticale :
  • UNION des fragments
  • JOINTURE sur la clé commune
  • DIFFÉRENCE
  • PRODUIT cartésien
La clé est dans chaque fragment, jointure sur cette clé.
10.Syntaxe pour accéder à une table distante via dblink ?
  • SELECT * FROM dblink.table;
  • SELECT * FROM table USING dblink;
  • SELECT * FROM "dblink"."table";
  • SELECT * FROM table@dblink;
Suffixe @nom_du_lien.
11.2PC — si UN seul site a voté « non » à la phase 2 :
  • On revote sans lui
  • On valide quand même (majoritaire)
  • On abandonne T sur tous les sites
  • On lance une nouvelle phase 1
Consensus = unanimité requise.
12.Pour qu'un trigger accède à :new et :old, il doit :
  • Être AFTER
  • Être déclaré sur une vue
  • Avoir la clause FOR EACH ROW
  • Utiliser DECLARE
Disponibles uniquement avec FOR EACH ROW.
13.Pour gérer un auto-incrément, on combine :
  • Trigger BEFORE INSERT FOR EACH ROW + séquence + NEXTVAL
  • Trigger AFTER INSERT + variable globale
  • Un index unique sur la colonne id
  • Une procédure stockée appelée par l'application
Pattern canonique du partiel : BEFORE INSERT FOR EACH ROW + :new.id := seq.NEXTVAL.
14.Code d'erreur valide pour RAISE_APPLICATION_ERROR ?
  • -1
  • +20012
  • -30000
  • -20012
Plage valide [-20999, -20000].
15.Un trigger INSTEAD OF s'applique :
  • Sur une table indexée par bitmap
  • À la place d'un BEFORE
  • Sur une vue non directement modifiable
  • Avant les LDD
Vues complexes (jointures, GROUP BY) → INSTEAD OF.
16.Dans la signature d'une procédure, p_nom IN VARCHAR2(50) est :
  • Correct
  • Correct mais déprécié
  • Incorrect : pas de taille dans la signature
  • Correct seulement avec %TYPE
Types sans taille dans la signature, point.
17.Un SELECT … INTO qui ne renvoie aucune ligne :
  • Lève TOO_MANY_ROWS
  • Lève NO_DATA_FOUND
  • Affecte NULL aux variables
  • Lève INVALID_CURSOR
ORA-01403, à gérer dans EXCEPTION.
18.Pour gérer un curseur sans risque d'oubli :
  • OPEN/FETCH/CLOSE manuel
  • Un trigger AFTER
  • FOR row IN cursor LOOP … END LOOP;
  • Une exception WHEN OTHERS
FOR cursor LOOP gère open/fetch/close automatiquement.
19.Pour journaliser une erreur même si la transaction métier rollback :
  • PRAGMA AUTONOMOUS_TRANSACTION
  • SAVEPOINT
  • Un trigger AFTER
  • Une fonction renvoyant un booléen
Transaction autonome = commit indépendant de la transaction appelante.
20.Dans un package, l'implémentation des procédures se trouve :
  • Dans la déclaration
  • Dans un trigger associé
  • Dans le PACKAGE BODY
  • Dans un fichier externe
Header = signatures publiques, body = code et privé.

Barème estimé

ScoreNiveauÀ faire
18-20 / 20ExcellentTu peux passer le partiel sereinement. Polis les exos pratiques.
14-17 / 20SolideRefais les chapitres concernés par tes erreurs. Travaille les annales.
10-13 / 20À renforcerReprends les flashcards et les Q/R des chapitres faibles.
< 10 / 20À travaillerRelire les CMs en profondeur. Commence par CM5/CM6 (PL/SQL pèse le plus).

📝 Questions de réflexion

Format partiel : réponses courtes (1-2 phrases). Réfléchis avant de déplier.

Pourquoi passer par des rôles plutôt que par des droits directs ?

Pour la maintenance (un nouvel utilisateur = un GRANT du rôle), la cohérence (un seul endroit définit les permissions d'un profil), et la réversibilité (désactiver le rôle sans toucher aux autres droits).

Différence entre REFRESH ON COMMIT et REFRESH ON DEMAND pour une VM ?

ON COMMIT rafraîchit à chaque validation sur les tables sources : VM toujours à jour, mais coût à chaque commit. ON DEMAND rafraîchit à la demande (dbms_mview.refresh) : VM potentiellement désynchronisée mais coût d'écriture nul.

Pourquoi un index bitmap ne convient pas à une table OLTP ?

Parce que chaque mise à jour d'une ligne reconstruit l'index entièrement. Sur une table avec des milliers d'inserts/updates par seconde (OLTP), c'est un suicide en performance. Le bitmap est conçu pour des tables à faible activité de MAJ (data warehouse, reporting).

Justifier une fragmentation H ou V sur un cas multi-sites.

Si 80% des requêtes locales filtrent sur la même valeur d'attribut (ville, classe), fragmentation H sur cet attribut → trafic réseau minimisé.
Si certaines colonnes sont rarement consultées ensemble (paie vs administratif), fragmentation V avec la clé dans chaque fragment → réduction de la taille des accès locaux et confidentialité.

Pourquoi un cluster est-il utile pour une relation Maître/Détails ?

Parce qu'il colocalise physiquement les lignes maître et détails partageant la même clé sur le disque. Les jointures fréquentes deviennent des lectures séquentielles au lieu d'allers-retours aléatoires. Gain de performance significatif quand on requête souvent ces jointures.

🧪 Problème pratique type partiel

Soit le MLD simplifié d'un producteur de vin :

Vin(id_vin, nom, annee, qtetot)
Commande(id_cmde, #id_client, date_cmde, total)
LigneCommande(id_lc, #id_cmde, #id_vin, qte, prix_unitaire)
Client(id_client, nom, ca_cumule)
Q1 — Écris un trigger BEFORE INSERT sur LigneCommande qui auto-incrémente id_lc à partir d'une séquence seq_lc.
CREATE OR REPLACE TRIGGER trig_id_lc
BEFORE INSERT ON LigneCommande
FOR EACH ROW
BEGIN
   :new.id_lc := seq_lc.NEXTVAL;
END;
Q2 — Écris un trigger AFTER INSERT qui décrémente Vin.qtetot à chaque ligne de commande insérée.
CREATE OR REPLACE TRIGGER trig_maj_qte_vin
AFTER INSERT ON LigneCommande
FOR EACH ROW
BEGIN
   UPDATE Vin
      SET qtetot = qtetot - :new.qte
      WHERE id_vin = :new.id_vin;
END;
Q3 — Écris un trigger garde-fou : refuse une commande si qte > Vin.qtetot.
CREATE OR REPLACE TRIGGER trig_check_stock_vin
BEFORE INSERT ON LigneCommande
FOR EACH ROW
DECLARE
   v_stock Vin.qtetot%TYPE;
BEGIN
   SELECT qtetot INTO v_stock
   FROM Vin WHERE id_vin = :new.id_vin;

   IF :new.qte > v_stock THEN
      RAISE_APPLICATION_ERROR(-20100, 'Stock insuffisant');
   END IF;
END;
Q4 — Écris une procédure Cumul_Depenses_Client(p_id) qui parcourt les commandes du client et renvoie son ca_cumule mis à jour.
CREATE OR REPLACE PROCEDURE Cumul_Depenses_Client(p_id IN NUMBER)
IS
   v_total NUMBER := 0;
   CURSOR c_cmds IS
      SELECT total FROM Commande WHERE id_client = p_id;
BEGIN
   FOR r IN c_cmds LOOP
      v_total := v_total + r.total;
   END LOOP;
   UPDATE Client SET ca_cumule = v_total WHERE id_client = p_id;
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('Client introuvable');
END;
Q5 — Soit 3 sites (Lille, Lyon, Toulouse). Comment fragmenter Client ? Comment écrire la vue de recomposition ?

Fragmentation horizontale de Client sur la ville :

Client_Lille    = σ(Client; ville = 'Lille')     @ Lille
Client_Lyon     = σ(Client; ville = 'Lyon')      @ Lyon
Client_Toulouse = σ(Client; ville = 'Toulouse')  @ Toulouse

Vue de recomposition sur le site central :

CREATE VIEW Client_complet AS
   SELECT * FROM Client@lille
   UNION
   SELECT * FROM Client@lyon
   UNION
   SELECT * FROM Client@toulouse;