Les curseurs PL/SQL Oracle : guide complet (implicite, explicite, FOR)

Curseurs PL/SQL Oracle : implicite vs explicite, OPEN/FETCH/CLOSE, boucle FOR, curseur paramétré et FOR UPDATE, avec exemples et bonnes pratiques.

Illustration : les curseurs PL/SQL Oracle

Un curseur PL/SQL est un pointeur vers le résultat d’une requête, qui permet de parcourir les lignes une à une. Oracle en distingue deux types — implicites (gérés automatiquement) et explicites (que vous déclarez et contrôlez) — plus la boucle FOR qui simplifie tout. Ce guide complet couvre la syntaxe, les attributs et les bonnes pratiques, avec des exemples concrets.

Publicité

🧪 Envie de pratiquer ? Exécutez les exemples de cet article dans notre SQL Playground gratuit — aucun logiciel à installer.

Curseur implicite vs explicite

  • Implicite : créé automatiquement par Oracle pour chaque SELECT INTO, INSERT, UPDATE, DELETE. Vous ne le déclarez pas, mais vous pouvez lire ses attributs (SQL%ROWCOUNT…).
  • Explicite : vous le déclarez pour traiter une requête qui ramène plusieurs lignes, avec un contrôle total (OPEN/FETCH/CLOSE).

Le curseur implicite

BEGIN
  UPDATE comptes SET solde = solde * 1.01 WHERE actif = 'O';
  DBMS_OUTPUT.put_line('Lignes mises à jour : ' || SQL%ROWCOUNT);
END;

Attributs disponibles : SQL%FOUND, SQL%NOTFOUND, SQL%ROWCOUNT, SQL%ISOPEN (toujours FALSE pour l’implicite).

Le curseur explicite : OPEN / FETCH / CLOSE

DECLARE
  CURSOR c_clients IS
    SELECT id, nom FROM clients WHERE ville = 'Paris';
  v_id   clients.id%TYPE;
  v_nom  clients.nom%TYPE;
BEGIN
  OPEN c_clients;
  LOOP
    FETCH c_clients INTO v_id, v_nom;
    EXIT WHEN c_clients%NOTFOUND;
    DBMS_OUTPUT.put_line(v_id || ' - ' || v_nom);
  END LOOP;
  CLOSE c_clients;
END;

Les attributs s’utilisent avec le nom du curseur : c_clients%FOUND, %NOTFOUND, %ROWCOUNT, %ISOPEN. Pensez à toujours fermer le curseur (sinon fuite de ressources).

La boucle FOR : la méthode recommandée

Elle ouvre, parcourt et ferme le curseur automatiquement — moins de code, moins d’erreurs :

BEGIN
  FOR r IN (SELECT id, nom FROM clients WHERE ville = 'Paris') LOOP
    DBMS_OUTPUT.put_line(r.id || ' - ' || r.nom);
  END LOOP;
END;

Plus besoin de déclarer les variables ni de gérer OPEN/FETCH/CLOSE. Préférez cette forme dans 90% des cas.

Curseur paramétré

DECLARE
  CURSOR c_par_ville(p_ville VARCHAR2) IS
    SELECT nom FROM clients WHERE ville = p_ville;
BEGIN
  FOR r IN c_par_ville('Lyon') LOOP
    DBMS_OUTPUT.put_line(r.nom);
  END LOOP;
END;

Curseur avec FOR UPDATE (verrouillage)

Pour modifier les lignes parcourues en toute sécurité :

DECLARE
  CURSOR c IS SELECT id, solde FROM comptes WHERE actif='O' FOR UPDATE;
BEGIN
  FOR r IN c LOOP
    UPDATE comptes SET solde = r.solde * 1.01 WHERE CURRENT OF c;
  END LOOP;
  COMMIT;
END;

WHERE CURRENT OF c cible exactement la ligne en cours. Pour aller plus loin sur les verrous, voir notre tutoriel sur la gestion des transactions.

Bonnes pratiques & performances

  • Évitez le « row-by-row » quand un seul ordre SQL suffit : un UPDATE … WHERE ensembliste est bien plus rapide qu’une boucle curseur.
  • Pour traiter de gros volumes ligne à ligne, utilisez BULK COLLECT et FORALL au lieu d’un FETCH unitaire.
  • Ancrez les variables sur les colonnes avec %TYPE / %ROWTYPE pour éviter ORA-06502.
  • Fermez toujours les curseurs explicites (la boucle FOR le fait pour vous).

FAQ

Quelle différence entre un curseur implicite et explicite ?

L’implicite est créé et géré par Oracle pour chaque ordre SQL ; l’explicite est déclaré et contrôlé par vous, pour parcourir plusieurs lignes.

Faut-il toujours fermer un curseur ?

Oui pour un curseur explicite ouvert avec OPEN. La boucle FOR IN s’en charge automatiquement.

Curseur ou requête ensembliste ?

Privilégiez toujours un ordre SQL unique (ensembliste) quand c’est possible : c’est plus rapide. Le curseur sert quand la logique ligne à ligne est inévitable.

Un nouveau tutoriel SQL par semaine

Nous ne spammons pas ! Consultez notre politique de confidentialité pour plus d’informations.

Publicité

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Cours SQL & Oracle — 100% gratuitVoir les cours →