Académique Documents
Professionnel Documents
Culture Documents
Plan du cours
1
Chapitre 2 : Le Langage PL/SQL
1. Introduction
2. Les types de curseurs
3. Les curseurs implicites
4. Les curseurs explicites
5. Les curseurs paramétrés
2
Introduction
Pour traiter une commande SQL, PL/SQL ouvre une zone de contexte pour
exécuter la commande et stocker les informations.
Cette zone de contexte est une mémoire de taille fixe, utilisée par le noyau pour
analyser et interpréter tout ordre SQL.
Le curseur explicite
Il est créé et géré par l'utilisateur pour traiter un ordre Select qui ramène
plusieurs lignes. Le traitement du select se fera ligne par ligne
Les curseurs explicites servent à retourner plusieurs lignes avec un select
3
Les curseurs
4
Attributs du curseur implicite
PL/SQL fournit des attributs permettant d’évaluer le résultat d’un curseur
implicite
Ces attributs sont utilisables comme des fonctions dans les ordres
PL/SQL MAIS PAS dans les commandes SQL.
Attribut Description
SQL%ROWCOUNT Entier : Nombre de lignes affectées par le dernier ordre
SQL
Booléen : TRUE si le dernier ordre SQL affecte au moins
SQL%FOUND une ligne
SQL%NOTFOUND Booléen : TRUE si le dernier ordre SQL n’affecte aucune
ligne
Exemple
DECLARE
V_Rows_Updated NUMBER;
BEGIN
UPDATE EMP
SET sal = sal*1.1
WHERE deptno = 10;
V_Rows_Updated := SQL%ROWCOUNT;
END ;
10
5
Application1: les curseurs implicites
Soit la relation :
Écrivez un bloc PLSQL qui effectue une augmentation de 200 euros du salaire
des employés du département 'Commercial' et qui utilise le curseur implicite pour
afficher le nombre d’employés affectés par ce changement.
11
Corrigé
DECLARE
total NUMBER(2);
BEGIN
UPDATE EMPLOYE
SET salaire = salaire + 200
WHERE DEPARTEMENT = 'Commercial';
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('Aucun salaire augmenté');
ELSIF SQL%FOUND THEN
total := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE( total || ' salaires ont été augmentés ');
END IF;
END;
12
6
Application 2: les curseurs implicites
Ecrivez un script récupérant le client de clé primaire la plus élevée, et ajoutant ce
client dans la table PERSONNE(num_pers, nom, ville, daten)
Declare
Row client%rowtype;
begin
select * into Row from client where num_client= (SELECT
MAX(num_client) FROM CLIENT) ;
13
Curseur explicite
Un curseur permet de "récupérer" un ensemble de
tuples, résultat d'une requête d'interrogation sur la base de données et de le manipuler de
manière procédurale, i.e. en balayant un par un les tuples/enregistrements.
Le rôle des curseurs est d'établir la transition entre l'univers BD et celui des langages
procéduraux classiques.
Définition: Un curseur est défini dans la partie déclarative d'un bloc PL/SQL par une
requête d'interrogation en SQL (sa structure correspond aux attributs du SELECT),
Exemple:
CURSOR C_pilote IS
SELECT num_pil, nom_pil FROM pilote
ORDER BY num_pil, nom_pil ;
14
7
Le curseur explicite
Pour traiter une requête qui retourne plusieurs lignes, l'utilisateur doit définir un curseur
qui lui permet d’extraire la totalité des lignes sélectionnées.
L’utilisation d'un curseur pour traiter un ordre Select ramenant plusieurs lignes, nécessite
4 étapes:
1. Déclaration du curseur
2. Ouverture du curseur
3. Traitement des lignes
4. Fermeture du curseur.
15
Exemple :
Declare
Cursor DEPT_10 is
select ename, sal
from emp
where depno = 10;
16
8
L'ouverture et la fermeture d’un curseur
La syntaxe :
OPEN nomcurseur [(nomparam1[,nomparam2 , . .)]
/* traitement des lignes */
CLOSE nomcurseur
Exemple :
Begin
…
OPEN DEPT_10
/* traitement des lignes*/
CLOSE DEPT_10
17
FETCH nomcurseur
INTO nomvariable |nomrecord
18
9
Exemple récapitulatif
Declare
Cursor DEPT_10 is select ename, sal from emp where depno = 10;
Vnom emp.name%TYPE ;
Vsalaire emp.sal%TYPE ;
Begin
OPEN DEPT_10;
LOOP
FETCH DEPT10 into vnom, vsalaire ;
--Traitement ligne
END LOOP ;
CLOSE DEPT_10;
End;
19
10
Les attributs:%Found
L'attribut %NotFound
Cet attribut est de type booléen (vrai ou faux)
Pour les curseurs implicites, cet attribut est vrai si les instructions insert, update,
delete traitent au moins une ligne.
Pour les curseurs explicites, il est vrai si le fetch ramène au moins une ligne.
21
L'attribut %RowCount
Cet attribut est de type numérique. Le curseur implicite indique le nombre de
lignes traités par les ordres insert, update, delete.
Le curseur explicite est incrémenté à chaque ordre fetch, donc cet attribut traduit
la nième ligne traitée.
22
11
L'attribut %Rowtype
Cet attribut permet la déclaration implicite d'une structure dont les éléments sont
d'un type identique aux colonnes ramenées par le curseur.
23
24
12
Boucle FOR pour un curseur
25
26
13
APPLICATION
Utilisez une boucle dans laquelle vous placerez une requête pour recopier les
couples nom/prénom ville et daten de la table CLIENT dans la table personne.
DECLARE
cursor c is
select * from client;
Begin
for row in c loop
insert into personne (num_pers, nom, ville, daten) values
(row.num_client, row.nom, row.ville, row.daten);
end loop;
end;/
27
DECLARE
CURSOR C1 IS
SELECT Cnom, Sal FROM chercheur WHERE Labno=10;
28
14
Application 3: les curseurs explicites
On considère la table suivante:
Écrivez un programme PL/SQL qui calcule la moyenne des salaires des pilotes
dont l’âge est entre 30 et 40 ans.
29
Corrigé
30
15
Les curseurs paramétrés
Définition: Un curseur paramétré est un curseur dont la requête contient des
variables dont les valeurs ne seront fixées qu’à l'ouverture.
Déclaration: On précise la liste des noms et des type des paramètres entre
parenthèses après le nom du curseur :
CURSOR / nom / (/liste des paramètres /) IS
/requête/
Par exemple, créons une requête qui, pour une mère donnée, nous donne la liste
des noms et prénoms de ses enfants :
CURSOR enfants ( numparent NUMBER) IS
SELECT
FROM PERSONNE
WHERE mere = numparent;
31
Par exemple,
OPEN enfants ( 1 ) ;
32
16
Boucle pour & curseurs paramétrés
La boucle pour se charge de l'ouverture, il convient donc de placer les paramètres
dans l'entête de la boucle,
Par exemple,
FOR e IN enfants ( 1 ) LOOP
DBMS_OUTPUT . PUT_LINE ( e . Nompers || ' ' || e . prenompers )
;
END LOOP ;
33
Remarques:
Le seul ordre qui offre le choix entre curseur implicite et explicite est
le SELECT lorsqu’il ne ramène qu’une seule ligne.
Il n’existe pas de curseur explicite de mise à jour
Un curseur explicite ne peut être qu’un SELECT : utiliser systématiquement des
CE pour les ordres SELECT
Inconvénients de CI par rapport au CE
34
17
Remarques:
Curseurs implicites: Gérés automatiquement par le noyau dans les cas suivants:
• Une instruction SELECT exécutée sous SQL Developer
• Une instruction SELECT donnant une seule ligne de résultat sous
PL/SQL
• Les instructions UPDATE, INSERT et DELETE
35
Récap
Jusqu’à présent, nous avons vu comment récupérer le résultat de requêtes SQL
dans des variables PL/SQL lorsque ce résultat ne comporte au plus qu’une seule
ligne.
Bien évidemment, cette situation est loin de représenter le cas général : les
requêtes renvoient très souvent un nombre important et non prévisible de lignes.
Dans la plupart des langages procéduraux au dessus de SQL, on introduit une
notion de “curseur” pour récupérer (et exploiter) les résultats de requêtes.
Un curseur est une variable dynamique qui prend pour valeur le résultat d’une
requête. La méthode pour utiliser un curseur est invariable. En premier lieu,
celui-ci doit être défini (dans la zone de déclaration).
36
18