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
Déclaration du curseur.
Remplissage du curseur par exécution de la requête associée.
Récupération des lignes une par une via un pointeur logique.
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 :
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.
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.
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;