Vous êtes sur la page 1sur 15

6

Utiliser des curseurs explicites

Objectifs

A la fin de ce TP, vous pourrez :

• distinguer les curseurs implicites des curseurs explicites

• énoncer les raisons d'utiliser des curseurs explicites

• déclarer et contrôler des curseurs explicites

• utiliser des boucles simples et des boucles FOR de curseur


pour extraire des données

• déclarer et utiliser des curseurs avec des paramètres

6-2

1
Contenu du TP

• Définition des curseurs explicites


• Utiliser des curseurs explicites
• Utiliser des curseurs avec des paramètres

6-3

Curseurs
A chaque instruction SQL exécutée par le serveur Oracle est
associé un curseur individuel :
• Un curseur implicite est déclaré et géré par le compilateur
PL/SQL pour toutes les instructions LMD et les instructions
PL/SQL SELECT.
• Un curseur explicite est déclaré et géré par le
programmeur.

Curseur implicite Curseur explicite

6-4

2
Fonctionnalités des curseurs explicites

Table
100 King AD_PRES
101 Kochhar AD_VP
102 De Haan AD_VP
. . .
. . .
. . .
139 Seo ST_CLERK

Ensemble actif =
140 Patel ST_CLERK
Résultat d’une . . .
requête multiligne

6-5

Contrôler les curseurs explicites

Non

Oui
DECLARE OPEN FETCH VIDE ? CLOSE

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


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

6-6

3
Contrôler les curseurs explicites

1 Ouverture du curseur
Pointeur
de curseur

2 Extraction d'une ligne


Pointeur
de curseur

Pointeur
3 Fermeture du curseur de curseur

6-7

Contenu du TP

• Définition des curseurs explicites


• Utiliser des curseurs explicites
• Utiliser des curseurs avec des paramètres

6-8

4
Déclarer un curseur

Syntaxe :
CURSOR cursor_name IS
select_statement;

Exemples :
DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;

DECLARE
v_locid NUMBER:= 1700;
CURSOR c_dept_cursor IS
SELECT * FROM departments
WHERE location_id = v_locid;
...

6-9

Exercice

Déclarer les curseurs suivants :

• c_dept_toronto pour extraire toutes les informations


relatives aux départements situés à Toronto.

• c_emp_toronto pour extraire les colonnes


employee_id, first_name et last_name
correspondant aux employés qui travaillent dans des
départements situés à Toronto.

6 - 10

5
Ouvrir le curseur

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

L'instruction OPEN
• exécute l'interrogation associée au curseur,
• identifie l'ensemble actif et
• positionne le pointeur de curseur sur la première ligne

Remarque : Si une interrogation ne renvoie aucune ligne lorsque le


curseur est ouvert, le code PL/SQL ne déclenche pas d'exception.

6 - 11

Extraire des données du curseur


DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
v_empno employees.employee_id%TYPE;
v_lname employees.last_name%TYPE;
BEGIN
OPEN c_emp_cursor;
FETCH c_emp_cursor INTO v_empno, v_lname;
DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);
END;
/

L'instruction FETCH
• lit les données de la ligne en cours et les
stocke dans les variables de sortie PL/SQL.
• fait passer le pointeur à la ligne suivante de
l'ensemble actif.

6 - 12

6
Extraire des données du curseur

DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
v_empno employees.employee_id%TYPE;
v_lname employees.last_name%TYPE;
BEGIN
OPEN c_emp_cursor;
LOOP
FETCH c_emp_cursor INTO v_empno, v_lname;
EXIT WHEN c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);
END LOOP;
END;
/

6 - 13

Fermer le curseur

...
LOOP
FETCH c_emp_cursor INTO empno, lname;
EXIT WHEN c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);
END LOOP;
CLOSE c_emp_cursor;
END;
/

L'instruction CLOSE
• désactive le curseur,
• libère la zone de contexte et
• annule la définition de l'ensemble actif.
Remarque : Bien qu'il soit possible de terminer le bloc PL/SQL sans fermer
les curseurs, prenez l'habitude de fermer les curseurs que vous déclarez
explicitement, afin de libérer les ressources.
6 - 14

7
Curseurs et enregistrements

Traitez les lignes de l'ensemble actif en extrayant les valeurs


pour les placer dans un enregistrement PL/SQL.
DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
v_emp_record c_emp_cursor%ROWTYPE;
BEGIN
OPEN c_emp_cursor;
LOOP
FETCH c_emp_cursor INTO v_emp_record;
EXIT WHEN c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_emp_record.employee_id
||' '||v_emp_record.last_name);
END LOOP;
CLOSE c_emp_cursor;
END;

6 - 15

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, de sortie et de
fermeture ont lieu de manière implicite.
• L'enregistrement est déclaré implicitement.

6 - 16

8
Boucles FOR de curseur

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

6 - 17

Attributs d'un curseur explicite

Utilisez des attributs de curseur explicite pour obtenir des


informations sur le statut d'un curseur.
Attribut Type Description

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

%NOTFOUND Booléen Prend la valeur TRUE si la plus récente


extraction ne renvoie pas de ligne
%FOUND Booléen Prend la valeur TRUE si la plus récente
extraction renvoie une ligne ; complément de
%NOTFOUND

%ROWCOUNT Nombre Prend la valeur correspondant au nombre total


de lignes renvoyées jusqu'à présent

6 - 18

9
Attribut %ISOPEN

•Vous ne pouvez extraire des lignes que 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 c_emp_cursor%ISOPEN THEN
OPEN c_emp_cursor;
END IF;
LOOP
FETCH c_emp_cursor...

6 - 19

%ROWCOUNT et %NOTFOUND : Exemple


DECLARE
CURSOR c_emp_cursor IS SELECT employee_id, last_name
FROM employees;
v_emp_record c_emp_cursor%ROWTYPE;
BEGIN
OPEN c_emp_cursor;
LOOP
FETCH c_emp_cursor INTO v_emp_record;
EXIT WHEN c_emp_cursor%ROWCOUNT > 10 OR
c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_emp_record.employee_id
||' '||v_emp_record.last_name);
END LOOP;
CLOSE c_emp_cursor;
END ; /

6 - 20

10
Boucles FOR de curseur utilisant
des sous-interrogations

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


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;
/

6 - 21

Exercice

Ecrire de deux façons différentes (avec la boucle LOOP et


avec la boucle FOR) un bloc PL/SQL qui utilise le curseur
c_emp_toronto, déclaré dans l’exercice précédent, et
affiche son contenu.

Rappel : c_emp_toronto permet d’extraire les colonnes


employee_id, first_name et last_name
correspondant aux employés qui travaillent dans des
départements situés à Toronto.

6 - 22

11
Contenu du TP

• Définition des curseurs explicites


• Utiliser des curseurs explicites
• Utiliser des curseurs avec des paramètres

6 - 23

Curseurs avec paramètres

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

• Transmettez les valeurs des paramètres au curseur au


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

6 - 24

12
Curseurs avec paramètres

DECLARE
CURSOR c_emp_cursor (deptno NUMBER) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = deptno;
...
BEGIN
OPEN c_emp_cursor (10);
...
CLOSE c_emp_cursor;
OPEN c_emp_cursor (20);
...

6 - 25

Curseurs avec paramètres

DECLARE
CURSOR c_emp_cursor (deptno NUMBER) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = deptno;
...
BEGIN
FOR emp_record IN c_emp_cursor (10);
...

6 - 26

13
Exercice

Ecrire de deux façons différentes (avec la boucle LOOP et avec


la boucle FOR) un bloc PL/SQL qui utilise un curseur
paramétré pour afficher l’identité (first_name et last_name) des
employés d’un département donné (department_id) et d’une
fonction données (job_id).

6 - 27

Quiz

Les curseurs implicites sont déclarés implicitement par PL/SQL


pour toutes les instructions LMD et pour les instructions
PL/SQL SELECT.
Le serveur Oracle ouvre implicitement un curseur pour traiter
chaque instruction SQL qui n'est pas associée à un curseur
déclaré explicitement.
a. Vrai
b. Faux

6 - 28

14
Synthèse

Ce TP vous a permis d'apprendre à :


• différencier les types de curseur :
– Les curseurs implicites sont utilisés pour toutes les
instructions LMD et pour les interrogations monolignes.
– Les curseurs explicites sont 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 les curseurs multilignes
• évaluer le statut des curseurs à l'aide des attributs
appropriés

6 - 29

Exercice

Ecrire de diverses façons

- Avec un curseur sans paramètre en utilisant la boucle LOOP


puis la boucle FOR
- Avec un curseur paramétré en utilisant la boucle LOOP puis
la boucle FOR

un bloc PL/SQL qui affiche les caractéristiques des employés


d’un département particulier, afficher aussi son adresse
complète (y compris les noms des pays et des régions).

6 - 30

15

Vous aimerez peut-être aussi