Vous êtes sur la page 1sur 26

7

Utiliser des curseurs explicites

Copyright © Oracle, 2004. Tous droits réservés.


Objectifs
A la fin de ce chapitre, vous pourrez :
• faire la différence entre un curseur implicite et un
curseur explicite
• déterminer quand et pourquoi utiliser un curseur
explicite
• déclarer et contrôler des curseurs explicites
• utiliser une boucle simple et une boucle FOR de
curseur pour extraire (fetch) des données
• déclarer et utiliser des curseurs avec des paramètres
• verrouiller des lignes à l'aide de la clause FOR
UPDATE
• référencer la ligne actuelle avec la clause WHERE
CURRENT

Copyright © Oracle, 2004. Tous droits réservés.


A propos des curseurs

A chaque instruction SQL exécutée par le serveur


Oracle est associé un curseur individuel :
• Curseurs implicites : déclarés et gérés par le
compilateur PL/SQL pour toutes les instructions
LMD et les instructions SELECT PL/SQL
• Curseurs explicites : déclarés et gérés par le
programmeur

Copyright © Oracle, 2004. Tous droits réservés.


Opérations de curseur explicite

Table
100 King AD_PRES
101 Kochhar AD_VP
Ensemble actif
102 De Haan AD_VP
. . .
. . .
. . .
139 Seo ST_CLERK
140 Patel ST_CLERK
. . .

Copyright © Oracle, 2004. Tous droits réservés.


Contrôler les curseurs explicites

Non

Oui
DECLARE OPEN FETCH VIDE? CLOSE

• Créer une • Identifier • Charger • Tester • Libérer


zone SQL l'ensemble la ligne l'existence l'ensemble
nommée actif en cours de lignes actif
dans des
variables • Si des
lignes
existent,
revenir à
FETCH

Copyright © Oracle, 2004. Tous droits réservés.


Contrôler les curseurs explicites

1 Ouverture du curseur
Pointeur de
curseur

2 Extraction (fetch)
d'une ligne
Pointeur de
curseur

Pointeur de
3 Fermeture du curseur
curseur

Copyright © Oracle, 2004. Tous droits réservés.


Déclarer le curseur

Syntaxe :
CURSOR cursor_name IS
select_statement;
Exemples :
DECLARE
CURSOR emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
DECLARE
locid NUMBER:= 1700;
CURSOR dept_cursor IS
SELECT * FROM departments
WHERE location_id = locid;
...

Copyright © Oracle, 2004. Tous droits réservés.


Ouvrir le curseur

DECLARE
CURSOR emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
...
BEGIN
OPEN emp_cursor;

Copyright © Oracle, 2004. Tous droits réservés.


Extraire des données du curseur

SET SERVEROUTPUT ON
DECLARE
CURSOR emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
empno employees.employee_id%TYPE;
lname employees.last_name%TYPE;
BEGIN
OPEN emp_cursor;
FETCH emp_cursor INTO empno, lname;
DBMS_OUTPUT.PUT_LINE( empno ||' '||lname);
...
END;
/

Copyright © Oracle, 2004. Tous droits réservés.


Extraire des données du curseur

Copyright © Oracle, 2004. Tous droits réservés.


Extraire des données du curseur

SET SERVEROUTPUT ON
DECLARE
CURSOR emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
empno employees.employee_id%TYPE;
lname employees.last_name%TYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO empno, lname;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( empno ||' '||lname);

END LOOP;
...
END;
/
Copyright © Oracle, 2004. Tous droits réservés.
Fermer le curseur

...
LOOP
FETCH emp_cursor INTO empno, lname;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( empno ||' '||lname);

END LOOP;
CLOSE emp_cursor;
END;
/

Copyright © Oracle, 2004. Tous droits réservés.


Curseurs et enregistrements

Traitez les lignes de l'ensemble actif en extrayant


(fetch) les valeurs pour les placer dans un
enregistrement PL/SQL.
DECLARE
CURSOR emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
emp_record emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO emp_record;
...

Copyright © Oracle, 2004. Tous droits réservés.


Boucles FOR de curseur

Syntaxe :
FOR record_name IN cursor_name LOOP
statement1;
statement2;
. . .
END LOOP;

• La boucle FOR de curseur simplifie le traitement


des curseurs explicites.
• Des opérations d'ouverture, d'extraction (fetch), de
sortie et de fermeture ont lieu de manière implicite.
• L'enregistrement est déclaré implicitement.

Copyright © Oracle, 2004. Tous droits réservés.


Boucles FOR de curseur

SET SERVEROUTPUT ON
DECLARE
CURSOR emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
BEGIN
FOR emp_record IN emp_cursor
LOOP
DBMS_OUTPUT.PUT_LINE( emp_record.employee_id
||' ' ||emp_record.last_name);
END LOOP;
END;
/

Copyright © Oracle, 2004. Tous droits réservés.


Attributs d'un curseur explicite

Obtenir les informations d'état concernant un curseur


Attribut Type Description

%ISOPEN Booléen Prend la valeur TRUE si le curseur


est ouvert
%NOTFOUN Booléen Prend la valeur TRUE si la dernière
D extraction (fetch) ne renvoie pas de
ligne
%FOUND Booléen Prend la valeur TRUE si la dernière
extraction renvoie une ligne ;
complément de %NOTFOUND
%ROWCOUN Nombre Prend la valeur correspondant au
T nombre total de lignes renvoyées
jusqu'à présent

Copyright © Oracle, 2004. Tous droits réservés.


Attribut %ISOPEN

• Extrayez (fetch) les lignes uniquement lorsque le


curseur est ouvert.
• Utilisez l'attribut de curseur %ISOPEN avant de
réaliser une extraction pour déterminer si le
curseur est ouvert.
Exemple :
IF NOT emp_cursor%ISOPEN THEN
OPEN emp_cursor;
END IF;
LOOP
FETCH emp_cursor...

Copyright © Oracle, 2004. Tous droits réservés.


Exemple d'utilisation des attributs
%ROWCOUNT et %NOTFOUND
SET SERVEROUTPUT ON
DECLARE
empno employees.employee_id%TYPE;
ename employees.last_name%TYPE;
CURSOR emp_cursor IS SELECT employee_id,
last_name FROM employees;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO empno, ename;
EXIT WHEN emp_cursor%ROWCOUNT > 10 OR
emp_cursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(TO_CHAR(empno)
||' '|| ename);
END LOOP;
CLOSE emp_cursor;
END ;
/

Copyright © Oracle, 2004. Tous droits réservés.


Boucles FOR de curseur utilisant
des sous-interrogations

Il n'est pas nécessaire de déclarer le curseur.


Exemple :
SET SERVEROUTPUT ON
BEGIN
FOR emp_record IN (SELECT employee_id, last_name
FROM employees WHERE department_id =30)
LOOP
DBMS_OUTPUT.PUT_LINE( emp_record.employee_id ||'

'||emp_record.last_name);
END LOOP;
END;
/

Copyright © Oracle, 2004. Tous droits réservés.


Curseurs avec paramètres

Syntaxe :
CURSOR cursor_name
[(parameter_name datatype, ...)]
IS
select_statement;

• Transmettez des paramètres au curseur au


moment de son ouverture et de l'exécution
de l'interrogation.
• Ouvrez un curseur explicite à plusieurs reprises,
en renvoyant un ensemble actif différent à chaque
fois.
OPEN cursor_name(parameter_value,.....) ;

Copyright © Oracle, 2004. Tous droits réservés.


Curseurs avec paramètres

SET SERVEROUTPUT ON
DECLARE
CURSOR emp_cursor (deptno NUMBER) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = deptno;
dept_id NUMBER;
lname VARCHAR2(15);
BEGIN
OPEN emp_cursor (10);
...
CLOSE emp_cursor;
OPEN emp_cursor (20);
...

Copyright © Oracle, 2004. Tous droits réservés.


Clause FOR UPDATE

Syntaxe :
SELECT ...
FROM ...
FOR UPDATE [OF column_reference][NOWAIT | WAIT n];

• Utilisez un verrouillage explicite pour interdire


l'accès aux autres sessions pendant la durée
d'une transaction.
• Verrouillez les lignes avant la mise à jour ou la
suppression.

Copyright © Oracle, 2004. Tous droits réservés.


Clause WHERE CURRENT OF

Syntaxe :
WHERE CURRENT OF cursor ;

• Utilisez des curseurs pour mettre à jour ou


supprimer la ligne en cours.
• Incluez la clause FOR UPDATE dans l'interrogation
du curseur pour verrouiller au préalable les lignes.
• Utilisez la clause WHERE CURRENT OF pour
référencer la ligne en cours à partir d'un curseur
explicite.
UPDATE employees
SET salary = ...
WHERE CURRENT OF emp_cursor;

Copyright © Oracle, 2004. Tous droits réservés.


Curseurs contenant
des sous-interrogations

Exemple :
DECLARE
CURSOR my_cursor IS
SELECT t1.department_id, t1.department_name,
t2.staff
FROM departments t1, (SELECT department_id,
COUNT(*) AS STAFF
FROM employees
GROUP BY department_id) t2
WHERE t1.department_id = t2.department_id
AND t2.staff >= 3;
...

Copyright © Oracle, 2004. Tous droits réservés.


Synthèse

Ce chapitre vous a permis d'apprendre à :


• différencier les types de curseur :
– curseurs implicites : utilisés pour toutes les instructions
LMD et les interrogations monolignes
– curseurs explicites : utilisés pour les interrogations portant
sur zéro, une ou plusieurs lignes
• créer et gérer des curseurs explicites
• utiliser des boucles simples et des boucles FOR de
curseur pour gérer plusieurs lignes dans les curseurs
• évaluer l'état du curseur en utilisant des attributs de
curseur
• utiliser les clauses FOR UPDATE et WHERE CURRENT OF afin
de mettre à jour ou de supprimer la ligne extraite actuelle

Copyright © Oracle, 2004. Tous droits réservés.


Présentation de l'exercice 7

Cet exercice porte sur les points suivants :


• déclarer et utiliser des curseurs explicites pour
interroger les lignes d'une table
• utiliser une boucle FOR de curseur
• appliquer des attributs de curseur pour contrôler
l'état du curseur
• déclarer et utiliser des curseurs avec des
paramètres
• utiliser les clauses FOR UPDATE et WHERE CURRENT
OF

Copyright © Oracle, 2004. Tous droits réservés.

Vous aimerez peut-être aussi