Vous êtes sur la page 1sur 19

Réalisé par : Mr SOUSSI Ahmed

Version : 2022 -2023


38

Objectifs du cours
1. Description du mécanisme de fonctionnement des curseurs

2. Traitement des curseurs : Déclaration, Ouverture, Exécution,

Fermeture, attributs de curseurs

3. Utilisation simplifiée des curseurs (les structures, la boucle For..In)

4. Les curseurs paramétrés.


39

Définition.

Un curseur est un pointeur vers une zone mémoire SQL privée

allouée (dans la mémoire PGA Programme Global Area) pour le

traitement d’une instruction SQL .

Le curseur permet de traiter un à un les enregistrements (lignes de

tables) ramenés par l’instruction SQL en question.


40

Types de curseur.
Deux types de curseurs peuvent être distingués :

 Curseur implicite : lorsqu’un utilisateur lance une commande


SQL, Oracle génère un curseur pour le traitement de cette
commande. Ce curseur créé et géré par Oracle est dit curseur
implicite.

 Curseur explicite : si vous souhaitez gérer une commande SQL


au sein de votre code PL/SQL, vous pouvez créer explicitement
un curseur pour traiter une à une les lignes ramenées par la
commande.
41

Curseur explicite. Syntaxe et exemple (1/2)

NO

YES

DECLARE OPEN FETCH Empty CLOSE

Voici un exemple :
FETCH C1 INTO nom, salaire;
DECLARE EXIT WHEN C1%NOTFOUND;
nom employees.last_name%TYPE; DBMS_OUTPUT.PUT_LINE ( nom||' gagne
salaire employees.salary%TYPE; '||salaire || ' dollars');
CURSOR C1 IS SELECT last_name, END LOOP;
NVL(salary,0) FROM employees; DBMS_OUTPUT.PUT_LINE
BEGIN (C1%ROWCOUNT);
OPEN C1; CLOSE C1;
LOOP END; /
42

Curseur explicite. Explication (2/2)

CURSOR C1: permet de déclarer un C1%NOTFOUND : renvoie VRAI si le


curseur portant le nom C1 curseur pointe au delà du dernier
nom employees.last_name%TYPE enregistrement. Contrairement à
signifie que la variable nom est de %FOUND.
même type que la colonne last_name de %ROWCOUNT qui renvoie le nombre
la table employees. de lignes ramenées par l’ordre SQL du
Open C1 : ouvre le curseur . curseur,
Fetch : ramène l’enregistrement %ISOPEN qui renvoie vrai si le curseur
courant et le charge dans les variables est ouvert.
nom et salaire et puis avance le pointeur Close C1 : permet de fermer le curseur
vers l’enregistrement suivant. et libérer les ressources.
43

Déclaration d’un curseur.


DECLARE
CURSOR <nom_curseur> IS <instruction SELECT>;

Exemple:
DECLARE
CURSOR emp_curseur IS SELECT employee_id, last_name FROM
employees;
CURSOR dept_curseur IS SELECT * FROM departments ORDER BY
department_id;
BEGIN
NULL;
END;
/
44

Ouverture d’un curseur.


OPEN <nom_curseur>;

 Ouvre le curseur pour exécuter la requête et identifier l’ensemble des


lignes.
 Si la requête ne retourne pas de ligne, aucune exception n’est signalée.

Exemple:

DECLARE
CURSOR emp_curseur IS SELECT employee_id, last_name
FROM employees;
BEGIN
OPEN emp_curseur;
END;
/
45

La clause FETCH.

FETCH nom_curseur INTO <variablE1, variablE2, … |


record_name %ROWTYPE>;

 Charger les valeurs de la ligne courante dans des variables de sortie.


 Prévoir le même nombre de variables.
 Tester si le curseur contient des lignes.
Les attributs d’un curseur.
Obtenir les informations d'état concernant 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 dernière
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
%ROWCOUNT Nombre Prend la valeur correspondant au
nombre total de lignes renvoyées
jusqu'à présent
47

Exemple1. curseur explicite

DECLARE
CURSOR emp_cur IS SELECT * FROM employees ORDER BY employee_id;
emp_rec employees%ROWTYPE;
BEGIN
OPEN emp_cur;
LOOP
FETCH emp_cur INTO emp_rec;
IF emp_cur%FOUND THEN
dbms_output.put_line('Employee ' || emp_rec.employee_id ||
' est : ' || emp_rec.last_name);
END IF;
END LOOP;
CLOSE emp_cur;
END;
/
 Corrigez cet exemple et déterminez ce qu’il affiche.
48

Exemple2. curseur explicite

DECLARE
CURSOR c1 is
SELECT last_name, employee_id, salary FROM employees
ORDER BY salary DESC;
my_name employees.last_name%TYPE;
my_empno employees.employee_id%TYPE;
my_sal employees.salary%TYPE;
BEGIN
OPEN C1;
LOOP
FETCH c1 INTO my_name, my_empno, my_sal;
EXIT WHEN (C1%ROWCOUNT > 5) OR (C1%NOTFOUND);
dbms_output.put_line('Employee ' || my_name || ' (' || my_empno || ') touche ' ||
my_sal);
END LOOP;
CLOSE c1;
END;
/
49

Curseur Implicite . Définition

Le curseur IMPLICITE est déclaré directement dans une structure FOR IN.
Cette structure permet de :
 Evite de déclarer le curseur dans la partie DECLARE.
 Avoir une Ouverture automatique du curseur (OPEN)
 Faire un FETCH automatique
 Avoir une Condition de sortie automatique
 Avoir Fermeture automatique du curseur

Syntaxe
FOR variable IN <nom_curseur> LOOP
--instructions
END LOOP;
50

Exemple1. curseur implicite

BEGIN

FOR emp_rec IN (SELECT * FROM employees ORDER BY employee_id)

LOOP
dbms_output.put_line('Employee #' || emp_rec.employee_id ||' est ' ||
emp_rec.last_name);
END LOOP;

END;
/
51

Exemple2. curseur implicite

Ecrire un bloc anonyme PL/SQL qui affiche la liste des employés soit leur nom, leur id et
leur salaire trié par salaire descendant. Utilisez un curseur implicite.
DECLARE
i number :=0;
BEGIN
FOR C1 IN (SELECT last_name, employee_id, salary FROM employees
ORDER BY salary DESC)
LOOP
i:=i+1;
dbms_output.put_line('Employee ' || C1.last_name || ' (' || C1.employee_id
|| ') touche ' || C1.salary);

EXIT WHEN i=5;


END LOOP;
END; /
52

Curseur explicite paramétré


 Un curseur paramétré peut servir plusieurs fois avec des valeurs des
paramètres différentes.
 On doit fermer le curseur entre chaque utilisation de paramètres
différents (sauf si on utilise « for » qui ferme automatiquement le
curseur)

DECLARE CURSOR <Nom_du_curseur> (param 1 type,


param 2 type,…) IS <instruction SELECT> ;
53

Exemple. curseur explicite paramétré

DECLARE employees du departement


CURSOR c(p_dept integer :=50) IS numero '||b||' sont :');
select department_id, last_name FOR employe IN c(b) LOOP
from employees dbms_output.put_line(employe.last
where department_id = p_dept; _name);
a number := &a; END LOOP;
b number := &b; dbms_output.put_line('Les
BEGIN employees du departement
dbms_output.put_line('Les numero 50 sont :');
employees du departement for employe in c loop
numero '||a||' sont :'); dbms_output.put_line(employe.last
FOR employe IN c(a) loop _name);
dbms_output.put_line(employe.last end loop;
_name); END; /
end loop;
dbms_output.put_line('Les Qu’affiche ce bloc PL/SQL

Vous aimerez peut-être aussi