Vous êtes sur la page 1sur 35

Institut Supérieur des Etudes Technologiques de Mahdia

UNITÉ D’ENSEIGNEMENT
PROGRAMMATION OBJET
AVANCÉE

NOTES DE COURS
PLSQL

MOUFIDAJGUIRIM@YAHOO.COM
A.U. 2019-2020
CHAPITRE III:

Les curseurs

2
OBJECTIFS DU CHAPITRE

A la fin de ce chapitre, vous saurez:

Faire la différence entre un curseur implicite et un curseur

explicite.

Ecrire un Record PL/SQL avec un curseur.

Ecrire un curseur dans une boucle For.

3
NOTION DE CURSEUR(1)

Chaque ordre SQL: SELECT, INSERT, DELETE ou


UPDATE alloue une zone de travail lors de son
exécution.
Cette zone est appelée curseur ( Context area).
PL/SQL discrimine deux curseurs différents:

Implicites Explicites
4
NOTION DE CURSEUR(2)

Un curseur implicite est une commande SQL


implicitement gérée par Oracle.

Il n’est pas préalablement défini dans la section


DECLARE.

C’est une commande parmi:


SELECT qui doit ramener une seule ligne.
INSERT, UPDATE et DELETE sans aucune contrainte sur
le nombre de n-uplets affectés.

5
NOTION DE CURSEUR(3)

Un curseur explicite est un curseur:


Déclaré dans la section DECLARE.

Géré par le développeur dans la section exécutable.

Est une généralisation du SELECT implicite pour ramener


n lignes que le développeur souhaite examiner.

La gestion de ce dernier consiste à:


Ouvrir le curseur,

Lire et traiter ses lignes,

Fermer le curseur. 6
NOTION DE CURSEUR(4)

Commandes SQL susceptibles de jouer le rôle de


curseur implicite et/ou explicite.

Opération Curseur implicite Curseur explicite


Mise à jour INSERT, UPDATE, Aucune
DELETE
Interrogation SELECT … INTO SELECT

7
CURSEURS IMPLICITES(1)

Commande SQL (SELECT, UPDATE, DELETE,


INSERT) située dans la partie exécutable.
Puisqu’il n’est pas déclaré, oracle lui désigne un nom
‘SQL’.
Ce nom sert au test de l’exécution du curseur appelé
statut à travers les attributs du curseur.
La gestion de ce type de curseur concerne:
Son ouverture,
Traitement des données retournées,
Fermeture.
Cette gestion est entièrement prise en charge par
PL/SQL, elle est automatique. 8
CURSEUR IMPLICITE: SELECT .. INTO (2)

Ce curseur d’interrogation doit retourner exactement


une seule ligne, autrement une erreur se produit.
SYNTAXE:

SELECT Col1, Col2,…., Coln


INTO V_Col1, V_Col2, ….., V_Coln
FROM ……
WHERE ……

L’affectation se fait à: une liste de variables ou à une


9
structure de type RECORD ou déclarée avec
%ROWTYPE.
CURSEUR IMPLICITE: SELECT .. INTO (3)

EXEMPLE1:

DECLARE
V_Lnom Laboratoire.Lnom%type;
V_Facno Laboratoire.Facno%type;
BEGIN Bloc anonyme avec
curseur implicite
SELECT Lnom, Facno qui cherche le nom,
INTO V_Lnom, V_Facno la faculté de
rattachement du
FROM Laboratoire laboratoire n°10
WHERE Labno=10;
…. 10

END;
CURSEUR IMPLICITE: SELECT .. INTO (4)

EXEMPLE2:

DECLARE
V_Nb NUMBER;
BEGIN
SELECT count(*) Bloc anonyme
avec curseur
INTO V_Nb implicite qui
FROM Chercheur compte le nombre
de chercheurs du
WHERE Labno=10; laboratoire n°10
….
END; 11
CURSEUR IMPLICITE: SELECT .. INTO (5)

EXCEPTIONS DU SELECT …INTO

Un curseur implicite ne ramenant pas une seule ligne


provoque une exception qui doit être levée (raise) et
gérée (handle) dans la section EXCEPTION.

Une exception est une situation nuisible qui empêche la


continuation dans la section exécutable du bloc.

Une exception levée et non gérée provoque la sortie du


bloc en échec.
12
CURSEUR IMPLICITE: SELECT .. INTO (6)

EXCEPTIONS DU SELECT …INTO


Exceptions susceptibles d’être levée pour un curseur
implicite:
Condition N° Exception Nom Exception
SELECT … INTO n’identifie ORA-01403 NO_DATA_FOUND
aucune ligne.
SELECT … INTO identifie ORA-01422 TOO_MANY_ROWS
plusieurs lignes.

SELECT… INTO ne retourne pas plusieurs lignes en cas:


Où la clause WHERE porte sur une clé primaire ou bien
colonne ayant un index unique.
13
Ne provoque aucune exception s’il calcule un résultat agrégé (
fonctions de groupes).
CURSEURS IMPLICITES: AUTRES (7)

Commandes SQL: INSERT, UPDATE et DELETE.

Pas de contraintes de cardinalité des n-uplets


manipulés pour ces curseurs.

Des exceptions spécifiques peuvent être levées. (Voir le


chapitre suivant).
14
CURSEURS IMPLICITES (8)

ATTRIBUTS DES CURSEURS IMPLICITES


L’état d’exécution d’un curseur est décrit à travers
quatre attributs.

Ces attributs sont accessibles par SQL%Nom_attribut


Nom_attribut TYPE Valeur et Explication
SQL%ROWCOUNT NUMBER Entier représentant le nombre de
lignes affectées par le dernier ordre
SQL.
SQL%FOUND BOOLEAN TRUE si le dernier ordre SQL affecte
au moins une ligne.
SQL%NOTFOUND BOOLEAN TRUE si le dernier ordre SQL
n’affecte aucune ligne. 15
SQL%ISOPEN BOOLEAN Toujours FALSE pour un curseur
implicite.
CURSEURS IMPLICITES (9)

ATTRIBUTS DES CURSEURS IMPLICITES


Utilisables comme des fonctions dans PL/SQL.

Ne sont pas valides dans les ordres SQL: elles sont


affectées dans des variables si nécessaire.

DECLARE INSERT INTO History_Tab


V_Rowcount NUMBER; VALUES (‘Lab10’, V_Rowcount,
BEGIN SYSDATE);
UPDATE chercheur SET Sal=Sal*1.1 /*
WHERE Labno=10; SQL%nomAttribut pour le curseur
V_Rowcount := SQL%ROWCOUNT; insert
/* SQL%nomAttribut pour update SQL%ROWCOUNT retourne 1
SQL%ROWCOUNT renvoie le nombre de SQL%ISOPEN retourne FALSE
*/ 16
lignes Maj.
SQL%ISOPEN retourne FALSE */ ….
END;
CURSEURS EXPLICITES(1)

Commande SQL SELECT déclarée et nommée et qui


ramène un nombre quelconque de lignes.

Possède les quatre attributs %ISOPEN, %FOUND,


%NOTFOUND, %ROWCOUNT.

Le traitement d’un curseur explicite se fait en quatre


étapes nécessaires:
Déclaration,
Ouverture,
Accès aux lignes du curseur,
Fermeture. 17
CURSEURS EXPLICITES(2)

1- DÉCLARATION DU CURSEUR
Consiste à nommer une requête et à lui associer
éventuellement des paramètres formels.
SYNTAXE:

CURSOR nom_curseur [(param1 [, param2,..)]]


IS
Commande_SELECT
[FOR UPDATE [OF col1, col2,….] [ NOWAIT]];

Les paramètres sont utilisables dans les clauses


18
WHERE, ORDER BY et dans les expressions.
CURSEURS EXPLICITES(3)
1- DÉCLARATION DU CURSEUR
Commande SQL: requête SWF incluant GROUP BY,
HAVING, ORDER BY…
Paramètre formel décrit comme suit:
Nom_paramètre [IN] TYPE [{ := | DEFAULT} valeur]
IN: mode de passage pas valeur.
TYPE: type PL/SQL sans contrainte de taille.
DEFAULT (ou :=) affecte une valeur par défaut.
[FOR UPDATE [OF col1, col2,….]: place un verrou sur les
n-uplets sources pour la construction des lignes du
curseur.
19
NOWAIT: en cas de verrou des n-uplets, il faut attendre
la libération pour qu’un autre processus puisse y accéder.
CURSEURS EXPLICITES(4)

1- DÉCLARATION DU CURSEUR
EXEMPLES:

DECLARE DECLARE DECLARE


…… ……. ……
CURSOR C1_Cher IS CURSOR C2_Cher (P_Labno CURSOR C3_Cher (P_Min
SELECT Cnom, Labno IN NUMBER) IS NUMBER DEFAULT 0,
FROM Chercheur SELECT Grade, Cnom P_Max NUMBER DEFAULT
WHERE Sal > 1200; FROM Chercheur 99) IS
WHERE Labno = P_Labno; SELECT ….
FROM ….
WHERE ….. BETWEEN
20
P_Min AND P_Max;
CURSEURS EXPLICITES(5)

2- OUVERTURE DU CURSEUR
SYNTAXE:
OPEN nom_curseur [ (paramètre_effectif,…)];

EXEMPLES:

OPEN C1_Cher(10); Equivalente à:


V_Labno:=10;
OPEN C2_Cher (V_Labno);
OPEN C2_Cher; Ouverture sans paramètre
OPEN C3_Cher(10,25);
OPEN C3_Cher; Ouverture avec valeurs par défaut
21
des paramètres
CURSEURS EXPLICITES(6)

2- OUVERTURE DU CURSEUR

A l’ouverture du curseur, l’ensemble actif de lignes est


construit, aucune ligne n’est encore accédée.

L’attribut du curseur %ROWCOUNT retourne la valeur


zéro.

Pointeur de
ligne
Ensembles de lignes
actif

22
CURSEURS EXPLICITES(7)

3- ACCÈS AUX LIGNES DU CURSEUR


SYNTAXE:
FETCH nom_curseur INTO var1, var2,….;

FETCH ….. INTO, utilisée dans une boucle, lie


séquentiellement les lignes de curseur dans l’ordre.

A chaque FETCH, le contenu de la ligne courante est


affecté aux variables de la clause INTO.

Les variables peuvent être des variables simples ou


23
composites.
CURSEURS EXPLICITES(8)

3- ACCÈS AUX LIGNES DU CURSEUR


EXEMPLE:
DECLARE OPEN C1_Cher;
CURSOR C1_Cher IS LOOP
SELECT Cnom, Labno FETCH C1_Cher INTO V_Cnom, V_Labno;
FROM Chercheur EXIT WHEN C1%NOTFOUND;
WHERE Sal > 1400; ………
V_Cnom Chercheur.Cnom%type; END LOOP;
V_Labno Chercheur. ………
Labno%type; END;
BEGIN
FETCH ramène les données de la ligne courante et
déplace le pointeur vers la ligne suivante. 24

EXIT WHEN contrôle la fin du curseur et termine la


boucle lorsque C1_Cher%NOTFOUND devient VRAI.
CURSEURS EXPLICITES(9)

4-FERMETURE DU CURSEUR
SYNTAXE:
CLOSE nom-curseur;

CLOSE libère l’espace mémoire alloué et aussi les verrous


éventuels.

Les opérations FETCH, CLOSE, %NOTFOUND,


%FOUND, %ROWCOUNT sur un curseur fermé
provoquent une exception spécifique INVALID_CURSOR.
25
CURSEURS EXPLICITES(10)

ATTRIBUTS D’UN CURSEUR EXPLICITE


Attribut Type Valeur Explication
%ISOPEN BOOLEAN TRUE Si le curseur est ouvert.
FALSE Si le curseur est fermé (ou non encore
ouvert).
%FOUND BOOLEAN TRUE Si le dernier FETCH ramène une ligne.
FALSE Si le dernier FETCH ne trouve plus une
ligne à ramener.
NULL Avant le premier FETCH (curseur ouvert).
%NOTFOUND BOOLEAN TRUE Si le dernier FETCH ne trouve plus une
ligne à ramener.
FALSE Si le dernier FETCH ramène une ligne.
NULL Avant le premier FETCH (curseur ouvert).
%ROWCOUNT NUMBER ENTIER Compteur qui s’incrémente après chaque
26
ligne lue (par FETCH).
ZERO Après OPEN et avant le premier FETCH.
CURSEURS EXPLICITES(11)

CURSEUR ET ENREGISTREMENT
SYNTAXE:
Nom_enregistrement nom_curseur%ROWTYPE;

EXEMPLE:
DECLARE LOOP
CURSOR C1 IS FETCH C1 INTO Rect1;
SELECT Cnom, Sal+NVL(prime,0) salai EXIT WHEN C1%NOTFOUND OR
FROM Chercheur C1%ROWCOUNT > 5;
WHERE Labno=10; V_Cnom := Rec1.Cnom;
Rec1 C1%ROWTYPE; V_Salaire := Rec1.salaire;
V_Cnom Chercheur.Cnom%type; END LOOP;
V_Salaire Chercheur.Sal%type; CLOSE C1;
27
BEGIN END;
OPEN C1;
CURSEURS EXPLICITES(12)

CLAUSE WHERE CURRENT OF ET FOR UPDATE


Les commandes SQL (UPDATE et DELETE) peuvent
utiliser la clause WHERE CURRENT OF nom_curseur
pour référencer la ligne courante d’un curseur explicite.

Une correspondante entre la ligne courante du curseur et


son n-uplet source à modifier ou bien à supprimer.

28
L’utilisation de cette clause exige que le curseur ait été
défini avec la clause FOR UPDATE (verrouillage).
CURSEURS EXPLICITES(13)

CLAUSE WHERE CURRENT OF ET FOR UPDATE


EXEMPLE:
DECLARE EXIT WHEN C1%NOTFOUND;
CURSOR C1 IS IF Ligne_C1.Labno = 10 THEN
SELECT Cnom, Labno UPDATE Chercheur
FROM Chercheur SET Labno = 99
WHERE Sal > 1400 FOR WHERE CURRENT OF C1;
UPDATE OF Labno; END IF;
Ligne_C1 C1%ROWTYPE; ……
BEGIN END LOOP;
OPEN C1; CLOSE C1;
LOOP COMMIT;
29
FETCH C1 INTO Ligne_C1; END;
CURSEURS EXPLICITES(14)

BOUCLE DÉDIÉE CURSEUR


PL/SQL offre une boucle FOR spéciale pour la
manipulation des curseurs explicites.

Cette boucle prend en charge la gestion automatique des


opérations d’exécution du curseur:
Ouverture (OPEN)

Lecture (FETCH)

Test de sortie (EXIT)

Fermeture (CLOSE)
30
Deux variantes de syntaxe selon le type du curseur:
nommé ou anonyme.
CURSEURS EXPLICITES(15)

BOUCLE DÉDIÉE CURSEUR


SYNTAXE1:

FOR nom_record IN nom_curseur [(paramètre,…)]


LOOP
…….
- - Traitement de la ligne courante
…….
END LOOP;

Correspond à un curseur explicite nommé c’est-à-dire


31
déclaré avant la boucle.
CURSEURS EXPLICITES(16)

BOUCLE DÉDIÉE CURSEUR

Nom_record implicitement déclaré comme variable


locale et de même structure que le curseur.

Nom_curseur est un curseur défini dans la section


DECLARE.

Les attributs du curseur sont disponibles dans la boucle et


non utilisables en dehors de cette dernière besoin de les
affecter dans des variables en cas de besoin.
32
CURSEURS EXPLICITES(17)

BOUCLE DÉDIÉE CURSEUR


EXEMPLE:
DECLARE
CURSOR C1 (P_daterec DATE) IS
SELECT Cnom, Grade
FROM Chercheur
WHERE DateRec < P_DateRec;
BEGIN
FOR Rec IN C1 (‘01-jan-99’) - - Curseur ouvert
LOOP - - ici une ligne est disponible
- - Traitement des lignes, une par itération
END LOOP;
- - Le curseur est fermé automatiquement. Les attributs ne sont pas utilisables.
………. 33
END;
CURSEURS EXPLICITES(18)

BOUCLE DÉDIÉE CURSEUR


Correspond à un curseur explicite anonyme c’est-à-dire
déclaré dans la boucle.
SYNTAXE2:
FOR nom_record IN (commande_SELECT)
LOOP
…….
- - Traitement de la ligne courante
…….
END LOOP;

L’ordre SELECT est une requête considérée comme un


34
curseur local anonyme et de ce fait n’a pas des
attributs accessibles.
CURSEURS EXPLICITES(19)

BOUCLE DÉDIÉE CURSEUR


EXEMPLE:
………
BEGIN
………
V_Tot_Sal NUMBER := 0;
FOR Rec IN ( SELECT Cnon, Sal
FROM Chercheur
WHERE Labno = 10 );
LOOP - - ici une ligne est disponible
- - Traitement de la ligne courante
IF Rec.Sal > 1000 THEN ……..
END LOOP; 35
……….
END;

Vous aimerez peut-être aussi