Paris-Saclay University

Bases de données 2

PL/SQL : curseurs

D'après le cours d'Emmanuel Waller

Pourquoi utiliser des curseurs ?

  • En PL/SQL, la récupération d'une ligne unique peut se faire simplement avec :
  • SELECT a, b INTO x, y FROM t WHERE clé = 123;
    • Cette requête récupère la première ligne correspondant au critère
    • Les valeurs sont placées dans les variables (x, y)
  • Problème : si la requête retourne plusieurs lignes, il est nécessaire d'utiliser un curseur pour gérer toutes les lignes du résultat.

Qu'est-ce qu'un curseur en PL/SQL ?

  • Un curseur est une zone mémoire nommée qui contient les résultats d'une requête SQL.
  • Caractéristiques d'un curseur :
    • Associé à une requête spécifique.
    • Peut stocker 0, 1 ou plusieurs lignes selon les résultats de la requête.
    • Sa taille est déterminée à l'exécution en fonction du nombre de lignes retournées.
  • Objectif : faciliter le traitement de plusieurs lignes en les stockant dans un espace dédié, accessible ligne par ligne.

Les étapes de fonctionnement d’un curseur

  1. Déclaration du curseur.
  2. Remplissage du curseur par exécution de la requête associée.
  3. Récupération des lignes une par une via un pointeur logique.
  4. Libération de la mémoire : le curseur devient inaccessible.

Exemple 1 : Récupérer le premier article

  • Table article(refart, nom, prixht)
  • Objectif : Afficher la référence du premier article par ordre alphabétique
  • Hypothèse : Il y a au moins un article dans la table
  • Problème : SELECT INTO est impossible s’il y a plusieurs lignes

Exemple : Déclaration d'un curseur

declare
    cursor c1 is
        select refart from article order by nom;
    art article.refart%type;
begin
    open c1;
    fetch c1 into art; -- affectation de variable (fetch into)
    dbms_output.putline(art);
    close c1;
end;

Exemple 2 : Utilisation des attributs de curseur

  • Objectif : Afficher la référence du premier article par ordre alphabétique, et du deuxième s’il existe.
  • Hypothèse : La table contient au moins un article.
  • Attributs du curseur :
    • c2%found : vrai si le dernier fetch a ramené une ligne.
    • c2%notfound : vrai si le dernier fetch n’a pas ramené de ligne.
    • c2%isopen : indique si le curseur est actuellement ouvert.

Comment parcourir un curseur en PL/SQL

  • Analogie : Le parcours d’un curseur fonctionne comme le parcours séquentiel d'un fichier.
  • Pointeur logique : Le curseur utilise un pointeur qui se déplace à chaque lecture.
  • Étapes du parcours :
    1. Ouvrir le curseur avec OPEN c :
      • Le pointeur logique est positionné avant la première ligne.
      • c%found est à vrai, indiquant que des données peuvent être lues.
    2. Lire une ligne avec FETCH c INTO a :
      • Le pointeur avance à la ligne suivante.
      • La ligne pointée est lue et stockée dans la variable a.
      • Si aucune ligne n’est disponible (fin du curseur), c%found devient faux.
    3. Fermer le curseur lorsque toutes les lignes sont lues pour libérer la mémoire.

Exemple 3 : Afficher toutes les références d’articles

On ne fait aucune hypothèse sur le nombre d’articles dans la table

Exemple : Déclaration d'un curseur (parcours complet)

declare
    cursor c3 is select refart from article order by nom;
    art article.refart%type;
begin
    open c3;
    fetch c3 into art;
    while c3%found loop
        dbms_output.putline(art);
        fetch c3 into art;
    end loop;
    close c3;
end;

Exemple 4 : Afficher référence et prix des articles

Exemple : Déclaration d'un curseur

declare
    cursor c4 is
        select refart, prixht
        from article;
    art c4%rowtype; -- type dérivé (curseur)
begin
    open c4;
    fetch c4 into art;
    while c4%found loop
          dbms_output.putline(art.refart || ' ' || art.prixht);
          fetch c4 into art;
    end loop;
    close c4;
end;

Curseurs et boucles : meilleure approche

cursor c;
for x in c loop
    print(x.a, x.b);
end loop;

loop
    fetch c into x;
    exit when c%notfound;
    dbms_output.put_line(x.a, x.b);
end loop;