Vous êtes sur la page 1sur 16

Le langage PL/SQL:

Les curseurs explicites


2 ARS

1
 Un curseur est une zone mémoire dédiée à l’analyse et l’exécution
d’une requête SQL
 Il existe deux types de curseurs :
 Les curseurs implicites
 Les curseurs explicites
 Le curseur implicite est géré automatiquement par Oracle
 Le curseur explicite est déclaré et géré par le programmeur

2
 À toute requête SQL, Oracle alloue une zone mémoire SQL privée
appelée curseur

 Un curseur implicite est créé pour toute opération de LMD, et toute


requête SQL retournant une seule ligne, dont le résultat sera affecté à
des variables.

 Un curseur explicite est créé par le programmeur pour gérer le


résultat d’une requête SELECT retournant plusieurs lignes.

3
Déclaration Ouverture Fetch Fermeture
• Nommer le •L’instruction •Charger les •L’instruction
curseur OPEN exécute données d’une CLOSE libère le
Vide
la requête ligne dans curseur actif
• Définir sa
SELECT une/plusieurs
requête
variables
SELECT

 OPEN : exécute la requête, identifie le résultat et place le curseur sur la première ligne
 FETCH : extrait la ligne courante et avance ensuite le curseur à la ligne suivante
 CLOSE : fermeture du curseur quand la dernière ligne est traitée. Le curseur est désactivé

4
 La syntaxe :

CURSOR cursor_name IS requete_select;

 Pas de clause INTO dans la déclaration. L’affectation aux variables


sera faite grâce à l’instruction FETCH
 La requête SELECT peut inclure des sous-requêtes, des jointures, des
fonctions de groupes/lignes etc.

5
 La syntaxe de l’ouverture :
OPEN cursor_name;
 La syntaxe du FETCH :
FETCH cursor_name INTO [variable1, variable2,…] | record_name ];
Exemple
LOOP
FETCH cursor_name INTO var1, var2;
EXIT WHEN…;

-- Traiter les données extraites

END LOOP;

 La syntaxe de la fermeture :
CLOSE cursor_name;
6
Attribut Type Commentaire
%ROWCOUNT Numérique Le nombre de lignes retrounés/affectés
par la requête SQL du curseur.
%FOUND Booleén Attribut booléen, renvoie TRUE si le fetch
le plus récent a renvoyé une ligne
%NOTFOUND Booléen La négation de SQL%FOUND
%ISOPEN Booleén Renvoie TRUE si le curseur est ouvert. Sa
Valeur est toujours FALSE pour les
curseurs implicites.

7
 Insérez les employés CLERK et de salaire < 1000 dans emp_tmp
(incluant uniquement les colonnes empno et ename)
Code PL/SQL
DECLARE
CURSOR emp_cursor IS SELECT empno, ename FROM emp WHERE
job=‘CLERK’ AND sal<1000;
emp_record emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO emp_record;
EXIT WHEN emp_cursor%NOTFOUND;
INSERT INTO emp_tmp VALUES (emp_record.empno, emp_record.ename);
END LOOP;
COMMIT;
CLOSE emp_cursor;
END;

8
 Reprise du même exemple avec la boucle
FOR record_name IN cursor_name LOOP
… instructions
END LOOP;
DECLARE
CURSOR emp_cursor IS SELECT empno, ename FROM emp WHERE
job=‘CLERK’ AND sal<1000;
BEGIN
FOR emp_record IN emp_cursor LOOP
--ouverture et FETCH implicites / et déclaration implicite de
--emp_record
INSERT INTO emp_tmp VALUES (emp_record.empno, emp_record.ename);
END LOOP;
--sortie de la boucle (après fin du parcours du curseur) et fermeture
du curseur implicites
COMMIT;
END;

9
 Reprise du même exemple avec la boucle
FOR record_name IN cursor_name LOOP
… instructions
END LOOP;
sans déclarer le curseur
BEGIN
FOR emp_record IN (SELECT empno, ename FROM emp WHERE job=‘CLERK’ AND sal<1000) LOOP
--ouverture et FETCH implicites
INSERT INTO emp_tmp VALUES (emp_record.empno, emp_record.ename);
END LOOP;
--sortie de la boucle (après fin du parcours du curseur) et fermeture
--du curseur implicites
COMMIT;
END;

10
 Il s’agit de définir des paramètres au curseur lors de sa déclaration
 Instanciation de ses paramètres lors de l’ouverture du curseur (et
donc lors de l’exécution de la requête du curseur)
 Utilité : ouvrir le curseur avec des valeurs (de paramètres) différentes
 Syntaxe :
CURSOR cursor_name[(param1 datatype , param2 datatype,…)]
IS req_select;
 Ouverture :
OPEN cursor_name(par_val1, par_val2,…);

11
 Afficher les employés CLERK du département 20, suivi par leur
nombre, ensuite, faire de même pour les SALESMAN du département 30
DECLARE
CURSOR emp_cursor(p_job VARCHAR2(30), p_deptno NUMBER) IS
SELECT empno, ename FROM emp WHERE job=p_job AND deptno=p_deptno;
emp_record emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor(‘CLERK’,20);
LOOP
FETCH emp_cursor INTO emp_record;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(emp_record.empno||’ ‘||emp_record.ename);
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘Nombre employés’||emp_cursor%ROWCOUNT);
CLOSE emp_cursor;
OPEN emp_cursor(‘SALESMAN’,30);
……
END;
12
 Syntaxe :
CURSOR cursor_name IS req_select
FOR UPDATE [OF(col)][NOWAIT|WAIT NB_SECONDES]
 Utilisation :
 Pour verrouiller les lignes d’un curseur dès son ouverture, afin de
les mettre à jour
 Les verrous ne seront libérés qu’à la fin de la transaction
(COMMIT/ROLLBACK)
 Le mot clé OF permet de verrouiller certaines colonnes, et non
toutes

13
 NOWAIT : fait que Oracle n’attende pas le déverrouillage des
lignes à modifier si elles sont déjà verrouillées par une autre
session alors Oracle génère une erreur.
 WAIT NB_SECONDES: si les lignes sont déjà verrouillés, Oracle
attend NB_SECONDES pour le déverrouillage, sinon l’ouverture
provoque une erreur.
 Le COMMIT doit être fait après la fermeture du curseur

14
 Syntaxe :
UPDATE table SET col=val WHERE CURRENT OF cursor_name;
 Utilisation :
 La clause WHERE CURRENT OF, située au niveau de l’instruction de
mise à jour (UPDATE ou DELETE), permet de référencer la ligne
courante d’un curseur

15
Exemple
DECLARE
CURSOR emp_cursor IS
SELECT ename, sal, deptno FROM emp WHERE deptno=20
FOR UPDATE OF sal NOWAIT;
BEGIN
FOR emp_rec IN emp_cursor LOOP
IF emp_rec.sal<2000 THEN
DBMS_OUTPUT.PUT_LINE(emp_rec.ename||’ ‘||emp_rec.sal);
UPDATE emp SET sal=sal*1.1 WHERE CURRENT OF emp_cursor;
END IF;
END LOOP;
COMMIT;
END;

16