You are on page 1of 34

Curseurs

1
Généralités
Un curseur est une zone mémoire qui permet de traiter individuellement
chaque ligne renvoyée par un SELECT

CURSEUR

SELECTION
BD

Types de curseurs :
 curseur implicite :
créé et géré par Oracle à chaque ordre SQL
 curseur explicite :
créé et géré par l'utilisateur afin de pouvoir traiter
un SELECT qui retourne plusieurs lignes
2
Les curseurs explicites doivent être déclarés Dans la section
DECLARE du bloc
Syntaxe
Cursor nom_curseur is
Requête_séléction ;

3
 Curseur (exemple)

Cursor C is
Select num_etudiant , prenom , nom
From etudiant
Where annee=’1’ ;

4
Curseur explicite

L'utilisation d'un curseur explicite nécessite 4 étapes :


1. déclaration du curseur
2. ouverture du curseur
3. traitement des lignes
4. fermeture du curseur

5
Ouverture d'un curseur : OPEN

Après avoir déclaré le curseur, il faut l'ouvrir dans la section exécutable


(BEGIN) afin de faire exécuter l'ordre SELECT :
OPEN nom_curseur ;

Exemple :

DECLARE
CURSOR c_emp IS SELECT * from
emp;
BEGIN
OPEN c_emp;

END ;

6
Traitement des lignes

Après l'exécution du SELECT, les lignes ramenées sont traitées une par une, la valeur de
chaque colonne du SELECT doit être stockée dans une variable réceptrice.
Utilisation de FETCH :
FETCH nom_curseur INTO liste_variables ;

c_emp1 Cursseur
Exemple : c_emp Cursseur nom sal
numemp nom sal com Toto 1200
123 Toto 1200 100 Tata 1300
124 Tata 1300 200 Titi 2300
125 Titi 2300 100

1- utilisation de %ROWTYPE 2- utilisation de %TYPE

DECLARE DECLARE
CURSOR c_emp1 IS SELECT name, sal from emp;
CURSOR c_emp IS SELECT * from emp; var 1 emp.nom%TYPE;
var c_emp%ROWTYPE; var2 emp.sal%TYPE
BEGIN BEGIN
OPEN c_emp; OPEN c_emp1;
FETCH c_emp INTO var; FETCH c_emp1 INTO var1,var2;
… …
END ; END ;
var 123 Toto 1200 100 7
Fermeture du curseur

Après le traitement des lignes, fermer le curseur :

CLOSE nom_curseur ;
1- utilisation de %ROWTYPE

Exemple : DECLARE

CURSOR c_emp IS SELECT * from emp;


var c_emp%ROWTYPE;
BEGIN
OPEN c_emp;
FETCH c_emp INTO var;
traitement

CLOSE c_emp;

END ;

8
Instructions pour les curseurs

Instruction Description

CURSOR nomCurseur IS requeteSelection; Déclaration du curseur


CURSOR zone1 IS SELECT brevet,
nbHVol, comp
FROM Pilote WHERE comp = 'AF';
OPEN numCurseur; Chargement des enregistrements dans le
curseur.
Si il n’y a pas d’enregistrement aucune
exception n’est levée
FETCH nomCurseur INTO Position du curseur sur l’enregistrement
{liste_var|nom_Enreg} suivant et chargement de
l’enregistrement courant dans une ou
plusieurs variables.
FETCH zone1 INTO var1,var2,var3;
CLOSE nomCurseur; Fermer le curseur.
Si une instruction essaye d’accéder au
9
curseur après sa fermeture l’exception
INVALID_CURSOR est levée
Instructions pour les curseurs

Instruction Description

nomCurseur%ISOPEN Retourne TRUE si le curseur est ouvert


IF zone1%ISOPEN THEN …
nomCurseur%NOTFOUND Retourne TRUE si le dernier FETCH n’a pas
renvoyé d’enregistrement (fin de
curseur).
EXIT WHEN zone1%NOTFOUND;
nomCurseur%FOUND Retourne TRUE si le dernier FETCH a
renvoyé un enregistrement
WHILE (zone1%FOUND) LOOP
nomCurseur%ROWCOUNT Retourne le nombre des lignes traités
jusqu’à présent

10
Parcours d’un curseur
LOOP …EXIT WHEN … END LOOP

DECLARE
CURSOR c_emp IS
SELECT ename, sal FROM emp WHERE deptno=10 order by sal ;
v_nom emp.ename%TYPE ;
v_sal emp.sal%TYPE ;

BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_nom, v_sal ;
EXIT WHEN c_emp%NOTFOUND ;

END LOOP ;
CLOSE c_emp ;
END;

11
Parcours d’un curseur
LOOP …EXIT WHEN … END LOOP
exemple :
declare
v emp%rowtype;
cursor vc is select * from emp;// rq raméne toutes les colonnes
begin
open vc;
loop
fetch vc into v;
dbms_output.put_line(v.ename);
exit when vc%notfound;
end loop;
close vc;
end;
/

12
Parcours d’un curseur
WHILE … LOOP… END LOOP

DECLARE
CURSOR c_emp IS
SELECT ename, sal FROM emp WHERE deptno=10 order by sal ;
enreg c

emp%ROWTYPE ;

BEGIN
OPEN c_emp;
FETCH c_emp INTO enreg;
WHILE (c_emp%FOUND) LOOP
IF enreg.sal > 2500 THEN
UPDATE emp SET comm=comm+10 where empno=enreg.empno;

END IF;
FETCH c_emp INTO enreg;
END LOOP ;
CLOSE c_emp ; 13
END;
Parcours d’un curseur
FOR facilite la programmation : évite les directives OPEN, FETCH et CLOSE
 La boucle s'arrête d’elle-même à la fin de l’extraction de la dernière ligne du
Curseur
 la variable de réception du curseur est aussi automatiquement déclarée
(%ROWTYPE du curseur).
Exemple :
DECLARE
CURSOR c_emp IS
SELECT * FROM emp WHERE deptno=10 order by sal ;

BEGIN
OPEN c_emp;
FETCH c_emp INTO … ;
FOR enreg IN c_emp LOOP
IF enreg.sal > 2500 THEN
UPDATE emp SET comm=comm+10 where empno=enreg.empno;
END IF;
END LOOP ;
CLOSE c_emp ;
END;
14
Parcours d’un curseur

FOR
Possibilité de déclaration du curseur dans la boucle FOR

Exemple :
DECLARE
CURSOR c_emp IS
SELECT * FROM emp WHERE deptno=10 orderby sal ;

BEGIN
FOR enreg IN (select * FROM emp deptno=10 order by sal) LOOP
IF enreg.sal > 2500 THEN
UPDATE emp SET comm=comm+10 where empno=enreg.empno;

END IF;
END LOOP ;

END;
15
Curseur paramétré
Un curseur peut posséder des paramètres d’entrée.
Objectif : utiliser un même curseur avec des valeurs différentes, dans un
même bloc PL/SQL
Le curseur doit être fermé entre chaque utilisation de paramètres différents
(sauf si on utilise « FOR» qui ferme automatiquement le
curseur)

DECLARE
CURSOR nomCurseur (par1 type, par2 type,…) IS select…
BEGIN
OPEN nom_c(val1, val2,…) ;

END;
 Type : char, number, date, boolean...
 Passage des valeurs des paramètres à l'ouverture du curseur.

16
Curseur paramétré

Exemple :

Déclaration du curseur avec


un seul paramètre.
DECLARE
CURSOR cur(p_dept number) IS SELECT deptno, ename FROM
emp where deptno = p_dept;
BEGIN Chargement et parcours
FOR employe in cur(10) LOOP du curseur en passant le
dbms_output.put_line(employe.ename); paramètre 10.
END LOOP;
FOR employe in cur(20) LOOP Chargement et parcours
dbms_output.put_line(employe.ename); du curseur en passant le
END LOOP; paramètre 20.
END;
/ 17
Curseur dynamique
Une variable curseur : REF CURSOR

Un curseur dynamique n’est pas associé à une requête donnée comme un curseur
classique statique
Une variable curseur est déclarée en deux étapes :
1- déclaration du type :
TYPE nomTypeCurseurDynamique IS REF CURSOR [RETURN typeRetourSQL];
2- déclaration de la variable du type :
nomCurseurDynamique nomTypeCurseurDynamique;

Le curseur dynamique est dit « typé » (strong) s’il inclut un type de retour

18
Curseurs dynamique non typés

19
Curseur dynamique
Exemple curseur dynamique non typé

20
curseur dynamique typé

21
Curseur dynamique
Exemple curseur dynamique typé

22
Curseur implicite
Pas déclaré par l’utilisateur
Utilisé par PL/SQL pour chaque opération du LMD de SQL (INSERT, UPDATE, DELET)
Les curseurs implicites sont tous nommés SQL
Attributs d’un curseur implicite :
Rq : nb de lignes supprimées et si update nb de ligne mis a jour
Attribut Explication
SQL%ROWACOUNT Nombre de ligne affectées par la dernière instruction LMD
SQL%FOUND Booléen valant TRUE si la dernièreinstruction LMD affecte au
moins un enregistrement
SQL%NOTFOUND Booléen valant TRUE si la dernièreinstruction LMD n’affecte au
aucun un enregistrement

Exemple :
BEGIN
DELETE FROM Pilote WHERE compa=‘AF’;
nbDelPilote :=SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE(‘nbre de pilote supprimé :’||nbdelpilote);
END;
/ 23
Les exceptions

24
Les Exceptions

Une exception est une erreur qui survient durant une exécution
2 types d’exception :
- prédéfinie par Oracle :
ex: déclenche l’exception ORA-01403 d’identificateur
NO_DATA_FOUND).
- définie par le programmeur

25
Exemple

26
La syntaxe générale d’un bloc d’exceptions :

27
Exceptions prédéfinies

28
Exceptions prédéfinies

l’erreur NO_DATA_FOUND, n’est opérationnelle qu’avec l’instruction


SELECT.
Une mise à jour ou une suppression (UPDATE et DELETE) d’un
enregistrement inexistant ne déclenche pas l’exception. Pour gérer ces cas
d’erreurs, il faut utiliser un curseur implicite et une exception utilisateur
(voir la section « Utilisation du curseur implicite »).

29
Les exceptions utilisateur (définies)

Doivent être déclarés avec le type EXCEPTION,


On les lève avec l’instruction RAISE

30
Traitement des exceptions

l ’exception utilisateur
DECLARE
doit être déclarée avec le
nomExeption1 Exception ;
type EXCEPTION

BEGIN
… RAISE nomExeption1 ; On lève l’exception avec l’instruction RAISE

EXCEPTION
WHEN nomExeption1 THEN
instructions
WHEN NO_DATA_FOUND THEN
instructions
….
WHEN OTHERS THEN
OTHERS : Toutes erreurs non interceptées
instructions
END ;

31
Exemple d’exception utilisateur

DECLARE
salaire number;
salaire_trop_bas EXCEPTION;
BEGIN
SELECT sal INTO salaire FROM emp where empno= 50;
if salaire < 300 THEN
RAISE salaire_trop_bas;
END IF;
EXCEPTION
WHEN salaire_trop_bas THEN
dbms_output.put_line(‘Salaire trop bas’);
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END;

- le message de l exception s’obtient par SQLERRM (SQLCODE)

32
Procédure RAISE_APPLICATION_ERROR

permet de définir ces propre messages et codes d’erreurs


Syntaxe :
RAISE_APPLICATION_ERROR(numerreur,message)
numErreur : valeur définie par l’utilisateur pour l’exception et comprise
entre -20000 et -20999
Message : chaîne de caractère (max 2048 octets) décrivant l’erreur
Peut être utilisé dans le code ou dans la section des exceptions

33
33
Procédure RAISE_APPLICATION_ERROR

Exemple :
DECLARE
salaire number;
BEGIN
SELECT sal INTO salaire FROM emp where empno= 50;
if salaire < 3000 THEN
RAISE_APPLICATION_ERROR(-20001,'salaire bas');
END IF;

delete from emp where empno=5000;


IF SQL%NOTFOUND then
RAISE_APPLICATION_ERROR(-20002,‘emp not exist!’);
END IF;
EXCEPTION
WHEN no_data_found then
RAISE_APPLICATION_ERROR(-20002,’salarié n’’existe pas’);
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END;
/

34

You might also like