Le carnet On est
Anti-sèche · à recopier sur le recto-verso autorisé

La feuille TAD

Rappel SQL complet + toute la syntaxe Oracle / PL-SQL dont tu peux avoir besoin, regroupée par thème, avec les notions de cours les plus susceptibles de tomber. Densité maximale pour un recto-verso.

0. Rappel SQL de base

SELECT — clauses & ordre logique

SELECT DISTINCT col1, col2 AS alias, COUNT(*)   -- 5. projection
FROM   t1 a JOIN t2 b ON a.id = b.id        -- 1. sources
WHERE  a.x > 10                              -- 2. filtre lignes
GROUP BY col1, col2                            -- 3. regroupe
HAVING COUNT(*) > 1                        -- 4. filtre groupes
ORDER BY col1 ASC, col2 DESC;             -- 6. tri

Ordre d'exécution : FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY. Limiter (Oracle) : WHERE ROWNUM <= 10 (avant tri) ou … ORDER BY x FETCH FIRST 10 ROWS ONLY (12c+).

Jointure

-- joint deux tables sur une condition d'égalité
SELECT e.nom, d.libelle
FROM emp e JOIN dept d ON e.dno = d.dno;
-- ancienne syntaxe équivalente : virgule + WHERE
SELECT e.nom, d.libelle FROM emp e, dept d WHERE e.dno = d.dno;

USING(col) remplace ON a.col = b.col quand la colonne porte le même nom.

Agrégation

SELECT dno, COUNT(*), SUM(sal),
       AVG(sal), MIN(sal), MAX(sal)
FROM emp
GROUP BY dno          -- toute col non agrégée
HAVING AVG(sal) > 2000;

WHERE filtre avant GROUP BY (sans agrégat) ; HAVING après (agrégats OK). COUNT(*)=lignes, COUNT(col)=non-NULL.

Opérateurs ensemblistes

q1 UNION q2      -- sans doublons
q1 UNION ALL q2  -- avec doublons (+ rapide)
q1 INTERSECT q2  -- lignes communes
q1 MINUS q2      -- dans q1 pas q2 (Oracle)

Règle : même nombre de colonnes + types compatibles ; ORDER BY seulement à la fin.

Sous-requêtes

-- dans WHERE : IN / comparateur (= si 1 seule valeur)
SELECT * FROM emp WHERE dno IN (SELECT dno FROM dept WHERE loc='PARIS');
SELECT * FROM emp WHERE sal > (SELECT AVG(sal) FROM emp);
-- corrélée (référence la requête externe)
SELECT * FROM emp e WHERE EXISTS (SELECT 1 FROM dept d WHERE d.dno=e.dno);
-- dans FROM (table dérivée, alias requis)
SELECT x.dno FROM (SELECT dno, AVG(sal) m FROM emp GROUP BY dno) x WHERE x.m>2000;

NOT IN + un NULL dans la liste ⇒ résultat vide : préférer NOT EXISTS. Filtres : = <> < >, BETWEEN a AND b, LIKE 'A%' (%=0..n, _=1 car.), IN(…), IS [NOT] NULL (jamais = NULL), priorité NOT > AND > OR.

LMD — manipulation

INSERT INTO emp (id, nom, sal) VALUES (1, 'Ali', 1500);
INSERT INTO archive (id, nom) SELECT id, nom FROM emp WHERE sal<1000;
UPDATE emp SET sal = sal*1.1, grade = 'B' WHERE dno = 10;
DELETE FROM emp WHERE sal < 800;        -- sans WHERE = tout !
-- MERGE : upsert (maj si présent, insère sinon)
MERGE INTO emp e USING src s ON (e.id = s.id)
  WHEN MATCHED THEN UPDATE SET e.sal = s.sal
  WHEN NOT MATCHED THEN INSERT (id, sal) VALUES (s.id, s.sal);

LDD — tables & contraintes

CREATE TABLE emp (
  id    NUMBER      PRIMARY KEY,                -- en ligne
  nom   VARCHAR2(50) NOT NULL,
  email VARCHAR2(80) UNIQUE,
  sal   NUMBER(8,2)  DEFAULT 0 CHECK (sal >= 0),
  dno   NUMBER,
  -- contraintes nommées (table-level) : recommandé
  CONSTRAINT fk_dept FOREIGN KEY (dno) REFERENCES dept(dno) ON DELETE SET NULL,
  CONSTRAINT ck_sal  CHECK (sal BETWEEN 0 AND 99999)
);
ALTER TABLE emp ADD tel VARCHAR2(15);   ALTER TABLE emp MODIFY nom VARCHAR2(80);
ALTER TABLE emp DROP COLUMN tel;          DROP TABLE emp;
TRUNCATE TABLE emp;   -- vide (rapide, non-rollback, garde la structure)

5 contraintes : PRIMARY KEY (unique+non NULL) · FOREIGN KEY … REFERENCES · NOT NULL · UNIQUE · CHECK ; + DEFAULT. DELETE=LMD (rollback) ; TRUNCATE/DROP=LDD (commit implicite).

Fonctions Oracle utiles

NVL(comm, 0)              -- NULL → 0   ·   COALESCE(a,b,c) = 1re non-NULL
DECODE(g,'A',100,'B',50,0)  -- if/then/else (else=0)
CASE WHEN sal>2000 THEN 'haut' ELSE 'bas' END
'M. '||nom            -- concat   ·   SUBSTR(nom,1,3)   ·   LENGTH(nom)
TO_CHAR(d,'DD/MM/YYYY')   TO_DATE('25/12/2025','DD/MM/YYYY')
SYSDATE   ROUND(x,2)   TRUNC(x)   SELECT SYSDATE FROM DUAL;  -- DUAL=table technique 1 ligne

1. CM1 — SPARC · users · rôles · vues encre bleue

SPARC = 3 niveaux : externe (vues par user) → conceptuel (modèle global) → physique (stockage). Niveau externe Oracle = users · rôles · vues. Rôles d'admin créés à la base : SYS, SYSTEM.

CREATE USER nom IDENTIFIED BY pwd
  DEFAULT TABLESPACE users
  TEMPORARY TABLESPACE temp;
-- à la création : AUCUN privilège
-- (pas même CREATE SESSION)
GRANT  priv|role TO   user|role;
REVOKE priv|role FROM user|role;
CREATE ROLE r [IDENTIFIED BY pwd];
SET ROLE r IDENTIFIED BY pwd;

Priv. système = CREATE/ALTER/DROP sur type d'objet. Priv. objet = SELECT INSERT UPDATE DELETE ALTER INDEX REFERENCES EXECUTE ; proc/fct/pkg → EXECUTE.

QC · rôle application vs utilisateur Rôle d'application : lié à un package, activé automatiquement à l'exécution d'un élément du package — seule façon de l'activer. Rôle utilisateur : tous les autres (peuvent être protégés par mot de passe). Prédéfinis : CONNECT, RESOURCE, DBA.

Vue logique = requête ré-exécutée, aucun stockage. Vue matérialisée (VM) = contenu dupliqué physiquement et rafraîchi (dé-normalisation perf). Doit contenir la clé primaire des sources. Privilèges VM : sys CREATE MATERIALIZED + obj GRANT SELECT sur les sources.

-- vue logique : filtre / projection
CREATE [OR REPLACE] VIEW v_client AS
  SELECT nom, prenom FROM Client WHERE ville = 'Cergy';
-- vue logique sur jointure (plusieurs tables)
CREATE VIEW v_cmd AS
  SELECT c.nom, k.id_cmde, k.total
  FROM Client c JOIN Commande k ON c.id = k.id_client;

-- vue matérialisée (stockée + rafraîchie)
CREATE MATERIALIZED VIEW LOG ON Client;   -- requis pour REFRESH FAST
CREATE MATERIALIZED VIEW vm
  REFRESH FAST ON COMMIT                     -- méthode + mode
  [BUILD DEFERRED]                          -- créée vide, peuplée au 1er refresh
  AS SELECT * FROM Client;
EXEC DBMS_MVIEW.REFRESH('vm');            -- refresh manuel (ON DEMAND)

Les vues réparties (recomposition de fragments H par UNION, V par JOINTURE) sont au §4 BDDR.

QC · rafraîchissement VM (tombe souvent) Modes (quand) : ON DEMAND (défaut, manuel) · ON COMMIT (à chaque commit des sources) · START WITH date NEXT intervalle. Méthodes (comment) : FAST (incrémental, exige un MATERIALIZED VIEW LOG) · COMPLETE (réexécute tout) · FORCE (défaut : FAST sinon COMPLETE).
QC · vue logique ou matérialisée ? (question de réflexion typique) VM si : données très demandées (lectures fréquentes) · requête coûteuse (jointures/agrégats complexes) · un léger décalage est tolérable (reporting, tableau de bord) → mode ON DEMAND. Vue logique si : données écrites souvent · fraîcheur critique · requête simple/peu coûteuse (le surcoût de rafraîchissement ne vaut pas le coup). Si cohérence critique mais lecture rare → VM ON COMMIT (chaque commit plus lourd).

2. CM2 — tablespaces · indexes · clusters encre verte

Hiérarchie de stockage : Base → Tablespace → Fichier → Segment → Extension → Bloc logique → bloc physique. 5 segments : Données · Index · Temporaire (tris, sinon SYSTEM) · Amorçage (dictionnaire, dans SYSTEM) · Rollback. 3 fichiers : .dbf données · .rdo/.log Redo Log · .ctl contrôle (min 1+2+1, dans init.ora).

QC · B-tree vs Bitmap (le classique) Sélectivité = distinctes / lignes. B-tree (défaut) : forte sélectivité (≈ clé primaire), ignore les NULL. Bitmap : faible sélectivité (sexe, statut), bcp de lignes, peu de MAJ, gère NULL1 MAJ ⇒ reconstruction totale (EE only).
QC · Cluster — optimise les jointures Maître/Détails : lignes de même clé stockées côte à côte sur le disque (colonnes communes non dupliquées). Remplace le tablespace. Index obligatoire sinon aucune opération.
CREATE [UNIQUE] INDEX i ON t(col [ASC|DESC]) TABLESPACE ts;
CREATE INDEX i ON t(col) REVERSE;     -- inversé ; annuler : ALTER INDEX i REBUILD NOREVERSE
CREATE INDEX i ON t(f(col));          -- par fonction (f DETERMINISTIC ; SYSDATE ne l'est PAS)
CREATE BITMAP INDEX i ON t(col);       -- faible sélectivité (EE)
CREATE CLUSTER c(col1 type1) SIZE n TABLESPACE ts;
CREATE TABLE t (…) CLUSTER c(colT);    CREATE INDEX i ON CLUSTER c;  -- OBLIGATOIRE
-- cluster d'une table existante : ① new table CLUSTER ② copier ③ drop ④ renommer

3. CM3 — transactions encre bordeaux

QC · ACID + cycle de vie Transaction = suite d'ops LMD (INSERT/UPDATE/DELETE) faite parfaitement et complètement, ou pas du tout. Les 4 propriétés ACID (natives à tous les SGBD-R) :
  • A — Atomicité : tout validé OU tout annulé, jamais d'état intermédiaire.
  • C — Cohérence : ne laisse jamais la base dans un état incohérent (contraintes respectées).
  • I — Isolation : ne voit aucune autre transaction en cours d'exécution.
  • D — Durabilité : succès confirmé ⇒ les résultats survivent, même à un crash serveur.
Commence en début de session OU à la fin de la précédente ; se termine par COMMIT ou ROLLBACK.
SAVEPOINT sp;
ROLLBACK TO SAVEPOINT sp;  -- annule jusqu'au jalon
ROLLBACK;   -- annule tout   COMMIT; -- valide
SET TRANSACTION READ ONLY; -- lecture consistante
CREATE PUBLIC SYNONYM s FOR objet;
CREATE SCHEMA AUTHORIZATION nom …;

QC · Isolation d'un SELECTvoit : données validées avant + ses propres MAJ ; ne voit pas les créations/MAJ en cours d'autres transactions. OLTP = transactions temps réel (banque, SNCF), natif Oracle. Schéma = associé à un user (même nom).

QC · Verrouillage & interblocage — verrou posé à chaque MAJ d'une ligne, libéré à la fin de la transaction. Deadlock : T1 attend un verrou tenu par T2 qui attend un verrou tenu par T1. Oracle annule l'opération de la transaction la plus jeune pour débloquer.

4. CM4 — bases de données réparties (BDDR) encre prune

BDDR = données sur plusieurs sites reliés par réseau. Conception : top-down (global → fragmenté) ou bottom-up (intégration de bases locales). Atouts : fiabilité, perf, croissance ; coûts : synchro, sécurité, interblocage distribué.

QC · 3 fragmentations (incontournable au problème BDDR) Horizontale = σ sélection (lignes) → recomposer par UNION. Verticale = π projection (colonnes) → recomposer par JOINTURE ; la clé doit figurer dans chaque fragment. Mixte = V puis H → recomposer par JOINTURE puis UNION. Horizontale dérivée = fragments définis par (semi-)jointure avec une table déjà fragmentée H.
QC · horizontale ou verticale ? (critère de choix) Horizontale (lignes) si chaque site exploite des lignes différentes de la même table — typiquement une répartition par valeur d'un attribut (géographique : site Paris ↔ clients de Paris, Lyon ↔ clients de Lyon). Verticale (colonnes) si chaque site exploite des attributs différents de la même entité — forte affinité entre certaines colonnes (ex : service Compta ↔ {id, salaire}, service RH ↔ {id, adresse}).
CREATE [PUBLIC] DATABASE LINK lien
  CONNECT TO user IDENTIFIED BY pwd
  USING 'nomService';
SELECT * FROM table@lien;
DROP DATABASE LINK lien;

Couche Oracle Net : listener.ora (connexions) · tnsnames.ora (alias).

-- recomposition H → UNION
CREATE VIEW V AS
  SELECT * FROM T@s1
  UNION SELECT * FROM T@s2;
-- recomposition V → JOINTURE (clé)
CREATE VIEW V AS
  SELECT T1.cle, T1.a, T2.b
  FROM T1@s1, T2@s2
  WHERE T1.cle = T2.cle;

Réplication (relation recopiée sur d'autres sites) via VM : CREATE MATERIALIZED VIEW image REFRESH FAST AS SELECT … FROM T@lien; — atout : disponibilité, lecture parallèle ; coût : cohérence des copies.

QC · Validation à 2 phases (2PC) — coordinateur C + sites Sᵢ, règle d'unanimité. ① Préparation : C écrit ⟨T préparée⟩, demande à tous ; chaque Sᵢ vote « prêt » ou « abandon ». ② Décision : tous OK → ⟨T validée⟩ + « valider » ; un seul « abandon » → ⟨T abandonnée⟩. Sᵢ accusent réception, puis C écrit ⟨T finie⟩. Reprise : panne avant décision → abandonner ; panne après décision connue → ne rien faire.

5. PL/SQL — bases & types encre sienne

DECLARE
  -- variables, types, curseurs
BEGIN
  -- SQL + instructions PL/SQL
EXCEPTION
  WHEN err THENEND;
-- debug : SET SERVEROUTPUT ON
DBMS_OUTPUT.PUT_LINE('x='||TO_CHAR(n));

Affectation : := · SELECT … INTO v · FETCH cur INTO v. %TYPE = type d'une colonne · %ROWTYPE = ligne entière.

v_prix  NUMBER(6,2);
v_nom   client.nom%TYPE;
v_lig   client%ROWTYPE;
TYPE t_rec IS RECORD(nom VARCHAR2(50), age NUMBER);
TYPE t_tab IS TABLE OF eleve.nom%TYPE
            INDEX BY PLS_INTEGER;   -- assoc (sparse)
TYPE t_arr IS VARRAY(7) OF VARCHAR2(8); -- borné
IF c1 THENELSIF c2 THENELSEEND IF;
LOOPEXIT WHEN cond; END LOOP;
FOR i IN deb..fin LOOPEND LOOP;
WHILE cond LOOPEND LOOP;
-- TABLE assoc (résiste aux trous)
i := t.FIRST;
WHILE i IS NOT NULL LOOP
  … ; i := t.NEXT(i);
END LOOP;
FOR i IN 1..v.COUNT LOOPEND LOOP; -- VARRAY

6. Triggers & séquences

CREATE [OR REPLACE] TRIGGER nom
  BEFORE|AFTER INSERT|DELETE|UPDATE [OF cols] ON tbl
  [FOR EACH ROW] [WHEN cond]
DECLAREBEGINEND;
-- plusieurs événements :
BEFORE INSERT OR DELETE ON tbl … IF INSERTING THENELSIF DELETING THENEND IF;
CREATE [OR REPLACE] TRIGGER nom INSTEAD OF INSERT ON vue BEGINEND;  -- vue non modifiable
QC · règles trigger:new / :old accessibles uniquement avec FOR EACH ROW (BEFORE peut modifier :new). Interdit de requêter la table en mutation dans le trigger ligne. BEFORE = valider/modifier ; AFTER = propager/logger ; INSTEAD OF = vue non modifiable (jointure, GROUP BY). Garde-fou : RAISE_APPLICATION_ERROR(code, 'msg'), code ∈ [-20999, -20000]. ALTER TRIGGER n ENABLE|DISABLE|COMPILE.
CREATE SEQUENCE seq [START WITH m] [INCREMENT BY n]   -- défauts : 1 et 1
  [MINVALUE k] [MAXVALUE p] [CYCLE|NOCYCLE] [CACHE l|NOCACHE];
seq.NEXTVAL  -- génère + incrémente     seq.CURRVAL  -- valeur courante

7. Procédures · fonctions · curseurs

CREATE [OR REPLACE] PROCEDURE nom(
  p_1 IN     NUMBER DEFAULT 0,
  p_2 OUT    VARCHAR2,
  p_3 IN OUT NUMBER)
IS            -- types SANS taille !
  v client.nom%TYPE;
BEGINEND;
CREATE [OR REPLACE] FUNCTION f(p IN NUMBER)
RETURN NUMBER IS BEGINRETURN v; END;

Appel : proc(args); · v := f(args); · SQL*Plus EXEC proc(a); / SELECT f(a) FROM DUAL;.

-- curseur explicite
CURSOR cur IS SELECT * FROM tbl;
v cur%ROWTYPE;
BEGIN
  OPEN cur;
  LOOP
    FETCH cur INTO v;
    EXIT WHEN cur%NOTFOUND;
    …
  END LOOP;
  CLOSE cur;
END;

Attributs : %FOUND %NOTFOUND %ISOPEN %ROWCOUNT.

FOR r IN cur LOOPEND LOOP;            -- FOR LOOP : open/fetch/close auto
FOR r IN (SELECTFROM …) LOOP-- curseur implicite sur SELECT
CURSOR c(p NUMBER) IS SELECTWHERE no=p;  OPEN c(12);     -- paramétré
SELECT col INTO v FROM … ;                  -- implicite (1 ligne attendue)
EXECUTE IMMEDIATE req INTO v USING param;  -- SQL dynamique

Transactions PL/SQL : COMMIT; · ROLLBACK [TO sp]; · SAVEPOINT sp; · SET TRANSACTION [READ ONLY] [NAME 'tr'];. Transaction autonome (log/audit indépendant) : PRAGMA AUTONOMOUS_TRANSACTION; + COMMIT; obligatoire. Une procédure stockée ne devrait pas commiter (laisser à l'appelant), sauf si autonome.

Fonctions natives (à connaître pour le problème) : || · SUBSTR(s,i,n) · LENGTH · TRIM · NVL(x,déf) · COALESCE · DECODE · TO_CHAR(d,'YYYY') · TO_DATE · TO_NUMBER · ROUND/TRUNC · NEXT_DAY · SYSDATE.

8. Exceptions & packages

EXCEPTION
  WHEN NO_DATA_FOUND THEN-- SELECT INTO vide (01403)
  WHEN TOO_MANY_ROWS THEN-- INTO multi → curseur (01422)
  WHEN DUP_VAL_ON_INDEX THEN-- doublon clé (00001)
  WHEN ZERO_DIVIDE THENWHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLCODE||' '||SQLERRM);

Exception perso : e EXCEPTION; PRAGMA EXCEPTION_INIT(e, -20001); puis RAISE e; et WHEN e THEN ….

-- header (signatures publiques)
CREATE [OR REPLACE] PACKAGE pkg IS
  c_PI CONSTANT NUMBER := 3.14;
  PROCEDURE logue(p IN VARCHAR2);
  FUNCTION  rech(id IN NUMBER) RETURN NUMBER;
END pkg;
-- body (implémentation + privé)
CREATE [OR REPLACE] PACKAGE BODY pkg IS
  PROCEDURE logue(p IN VARCHAR2) IS BEGINEND;
END pkg;

Chargé en mémoire au 1ᵉʳ appel ; variables globales partagées sur la session.

Patterns d'examen — à écrire les yeux fermés

Le problème PL/SQL (~6 pts) tombe sur ces structures ; le problème BDDR (~6 pts) sur la recomposition de vues réparties.

① Auto-incrément (BEFORE INSERT + séquence)

« Écrire un trigger attribuant automatiquement la clé primaire de tbl à partir de la séquence seq_tbl. »

CREATE OR REPLACE TRIGGER trig_id
BEFORE INSERT ON tbl FOR EACH ROW
BEGIN
  :new.id := seq_tbl.NEXTVAL;
END;

② Garde-fou (RAISE_APPLICATION_ERROR)

« Écrire un trigger qui interdit la mise à jour de la quantité en stock à une valeur négative. »

CREATE OR REPLACE TRIGGER trig_chk
BEFORE UPDATE OF qte ON tbl FOR EACH ROW
BEGIN
  IF :new.qte < 0 THEN
    RAISE_APPLICATION_ERROR(-20100, 'qte < 0');
  END IF;
END;

③ Trigger de cumul (AFTER INSERT)

« À chaque nouvelle commande, mettre à jour le cumul des dépenses (CA) du client concerné. »

CREATE OR REPLACE TRIGGER trig_ca
AFTER INSERT ON commande FOR EACH ROW
BEGIN
  UPDATE client SET cumul = cumul + :new.total
  WHERE id = :new.id_client;
END;

④ Procédure défensive (curseur + exception)

« Écrire une procédure qui affiche toutes les commandes d'un client (donné par son id), en gérant le cas où il n'existe pas. »

CREATE OR REPLACE PROCEDURE liste(p_id IN NUMBER)
IS
  CURSOR c IS SELECT id, total FROM Commande
            WHERE id_client = p_id;
  v_nom Client.nom%TYPE;
BEGIN
  SELECT nom INTO v_nom FROM Client WHERE id=p_id;
  FOR r IN c LOOP
    DBMS_OUTPUT.PUT_LINE(r.id||' '||r.total);
  END LOOP;
EXCEPTION
  WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('introuvable');
END;

⑤ INSTEAD OF sur vue de jointure

« La vue (jointure parent/enfant) n'est pas modifiable : écrire un trigger permettant d'y insérer une ligne (le parent est créé s'il n'existe pas). »

CREATE OR REPLACE TRIGGER trig_v
INSTEAD OF INSERT ON vue_jointe
DECLARE v_id parent.id%TYPE;
BEGIN
  BEGIN
    SELECT id INTO v_id FROM parent WHERE nom=:new.np;
  EXCEPTION WHEN NO_DATA_FOUND THEN
    INSERT INTO parent VALUES(seq.NEXTVAL, :new.np)
      RETURNING id INTO v_id;
  END;
  INSERT INTO enfant VALUES(seq2.NEXTVAL, :new.ne, v_id);
END;

🎯 Questions de cours — à ne pas rater

Notions conceptuelles les plus susceptibles en QCM / réflexion (les moins évidentes à retenir).

  • Rôle application = activé auto par un package (seule façon) ; rôle user = le reste.
  • VM : ON COMMIT vs ON DEMAND ; FAST exige un MV LOG, COMPLETE réexécute, FORCE = défaut.
  • B-tree : forte sélectivité, pas de NULL ; Bitmap : faible sélectivité, gère NULL, 1 MAJ ⇒ reconstruction.
  • Cluster : maître+détails côte à côte, jointure rapide, index obligatoire.
  • Isolation : un SELECT ne voit pas les MAJ non validées des autres transactions.
  • Deadlock : Oracle annule l'opération de la transaction la plus jeune.
  • Fragmentation : H→UNION · V→JOINTURE (clé partout) · mixte→JOINTURE puis UNION · dérivée.
  • 2PC : unanimité ; préparation (vote) puis décision ; reprise selon panne avant/après décision.
  • Réplication : disponibilité + lecture parallèle, mais cohérence des copies à gérer.
  • :new/:old seulement avec FOR EACH ROW ; pas de requête sur table en mutation.
  • BEFORE = valider/modifier ; AFTER = propager/logger ; INSTEAD OF = vue non modifiable.
  • RAISE_APPLICATION_ERROR : code ∈ [-20999, -20000].
  • Transaction autonome : PRAGMA AUTONOMOUS_TRANSACTION + COMMIT ; indépendante de l'appelant.
  • NO_DATA_FOUND (INTO vide) · TOO_MANY_ROWS (INTO multi → curseur) · DUP_VAL_ON_INDEX.
  • Package = header (public) + body (impl + privé) ; chargé en mémoire au 1ᵉʳ appel.