Vous êtes sur la page 1sur 38

Université Paris Nanterre

Cours Programmation en PL/SQL

Sonia GUEHIS
sonia.guehis@parisnanterre.fr
PLAN DU COURS
q Introduction

q Variables et déclaration

q Structures conditionnelles et itératives

q Les curseurs et curseurs paramétrés

q La gestion des exceptions

q Les procédures stockées

q Les fonctions

q Les packages

q Les triggers 2
Informations utiles
q Volume Horaire: 16,5 CM + 16,5 TD

q Coefficient: 3 Crédits

q Responsable de cours: Sonia Guehis

q Responsable de TD: Sonia Guehis (TD1) & Mayssa Tayachi (TD2)

q Modalités d’évaluation: TPs notés à rendre comme notes de


contrôle continue (50%) + Examen (50%)

q Outil utilisé: SQLdeveloper ( à télécharger et installer), une


connexion au serveur Oracle de la Miage de Nanterre.

3
Pourquoi PL/SQL ?
l SQL est un langage non procédural

l Le développement d’application autour d’une BDR nécessite d’utiliser :


Ø des variables

Ø des structures de contrôle de la programmation (boucles et itérations)

Ø Besoin d’un langage procédural pour lier plusieurs requêtes SQL avec des
variables et utiliser les structures de contrôle habituelles .

l D’où PL/SQL (Acronyme : ProceduraL SQL) : langage de programmation


procédural et structuré pour développer des applications autour de bases
de donnes relationnelles (SQL)

4
PL/SQL
l PL/SQL est un langage propriétaire de Oracle
l Pas de véritable standard, la plupart des SGBD relationnels propose des
L4G (langage de 4ième génération) spécifiques, semblables à PL/SQL.
l PL/SQL = Extension de SQL : des requêtes SQL cohabitent avec les
structures de contrôle habituelles de la programmation structurée (blocs,
alternatives, boucles)
l La syntaxe ressemble au langage Ada
l Un programme est constitué de variables, procédures et fonctions
l PL/SQL permet :
– l'utilisation de variables permettant l’échange d’information entre les requêtes SQL et le
reste du programme : ces variables sont de type simple ou structuré dynamique.

– des traitements plus complexes, notamment pour la gestion des cas particuliers et des
erreurs (traitement des exceptions),
– l'utilisation de librairies standards prédéfinies (supplied PLSQL packages)

5
Cas d'utilisation
l Le PL/SQL peut être utilisé sous 3 formes :
ü un bloc de code exécuté comme une commande SQL, via un interpréteur

standard (SQL+ ou iSQL*PLus)

ü un fichier de commande PL/SQL

ü un programme stocké (procédure, fonction, package ou trigger)

l Ainsi PL/SQL peut être utilisé :


ü pour l’écriture de procédures stockées et des triggers

ü pour l’écriture de fonctions utilisateurs qui peuvent être utilisées dans les
requêtes SQL (en plus des fonctions prédéfinies) dans des outils Oracle,
Forms et Report en particulier

6
Les commandes
• Les commandes supportées par PL/SQL sont les instructions SQL :
1- Pour le LMD :
• Insert
• Update
• Delete
• Select

2- Pour la gestion des transactions :


• Commit, Rollback…

7
Structure d'un programme PL/SQL
• Un programme est structuré en blocs d’instructions de 3 types :
- Procédures anonymes
- Procédures nommées
- Fonctions nommées

• Structure d’un bloc :

[DECLARE]
- définitions de variables, constantes, exceptions, curseurs
BEGIN
- les instructions à exécuter: ordres SQL, instructions PL/SQL,
structures de contrôles

[EXCEPTIONS]
- la récupération des erreurs (traitement des exceptions)
END ;

• Remarques :
Ø Un bloc peut contenir d’autres blocs
8
Ø Seuls begin et end sont obligatoires
Ø Les blocs comme les instructions se termine par un « ; »
Les variables dans PL/SQL
l Identificateurs sous Oracle (insensible à la case Maj/Min): 30 caractères au plus

l Commence par une lettre

l Peut contenir : lettres, chiffres, _, $ et #

• Portée habituelle des langages à blocs

• Doivent être déclarées avant d’être utilisées

• Commentaires :
– Pour une fin de ligne
/* Pour plusieurs lignes */

• Les types habituels correspondants aux types SQL2 ou Oracle : integer, varchar,...

• Les types composites adaptés à la récupération des colonnes et des lignes des tables
SQL : %TYPE, %ROWTYPE

9
Déclaration de variables
l Identificateur [CONSTANT] type [:= valeur];
l Ex :
age integer;
nom varchar(30);
dateNaissance date;
ok boolean := true;

l Déclarations multiples interdites !!!! (I, j integer ; interdit !)

l %TYPE
ü Déclaration qu’une variable est du même type qu’une colonne d’une table
ou d’une vue (ou qu’une autre variable) :
ü Ex : nom emp.nome.%TYPE;
déclare que la variable « nom » contiendra une colonne de la table emp

l %ROWTYPE
• Une variable peut contenir toutes les colonnes d’une ligne d’une table/vue
• Ex : employe emp%ROWTYPE;
10
déclare que la variable « employe » contiendra une ligne de la table emp
Exemple
DECLARE
employe emp%ROWTYPE;
nom emp.nome.%TYPE; …

BEGIN
SELECT * INTO employe FROM emp WHERE matr = 900;

nom := employe.nome;

employe.dept := 20;

employe.matr:=955;

...
INSERT INTO emp VALUES employe; ...

END ;

11
Types de données sous PL/SQL

• Types de données standards SQL : char, date, number, etc.

l Types intégrés dans PL/SQL : boolean, binary, integer

l Types structurés PL/SQL : record, table

l Structures de données pour la gestion de résultats de requêtes : cursor

l Types de données définis par les utilisateurs

12
Le type RECORD
l Equivalent à struct du langage C

• Syntaxe :

TYPE nomRecord IS RECORD ( champ1 type1, champ2 type2, ...);

• Exemple :
TYPE emp2 IS RECORD (
matr integer,

nom varchar(30)
);

employe emp2;

employe.matr := 500;

13
Affectation et conflits
Ø Plusieurs façons d’affecter une valeur à une variable :
- Par «:= »
- Par la directive INTO de la requête SELECT

Ø Exemples :
dateNaissance := ‘09/09/2015’;
• SELECT nome INTO nom FROM emp WHERE matr = 125;

Ø Conflits de noms :
Si une variable porte le même nom qu’une colonne d’une table, c’est la
colonne qui l’emporte :

14
Exemple pour s’exercer
Soit le schéma de la base Agence suivant:
ü immeuble (Adr, NbEtg, DateConstr, NomGerant)
ü appart (Adr, Num, Type, Superficie, Etg, NbOccup)
ü personne (Nom, Age, CodeProf)
ü occupant (Adr, NumApp, NomOccup, DateArrivee, DateDepart)
ü propriete (Adr, NomProprietaire, QuotePart)

Déclarations de variables
DECLARE
nomPersonne CHAR(10) := ‘Charles';
monAdr CONSTANT CHAR(20):= ‘200 avenue de la Républiqueimm’;
etage appart.Etg%TYPE;
monImmeuble immeuble%ROWTYPE;

BEGIN
SELECT * INTO monImmeuble FROM immeuble WHERE Adr=monAdr; SELECT Etg INTO
etage FROM appart
WHERE Adr=monImmeuble.Adr AND Num=10;
INSERT INTO personne VALUES(nomPersonne, 35, 'ING');
END;
15
Les entrées / Sorties
q PaquetageDBMS_OUTPUT
Ø ENABLE; -- permet les entrées/sorties
Ø DISABLE; -- désactive les entrées/sorties
Ø PUT (in valeur); -- affichage valeur chaine de caractères/ numérique/ date
Ø NEW_LINE; -- retour à la ligne
Ø PUT_LINE (in valeur); -- même chose avec retour à la ligne
Ø GET_LINE (out varChaine, out état); -- lecture d'une ligne dans varChaine état est 0 si tout est
en règle
Ø GET_LINES (out varTabChaines, in out nbLignes); -- lecture de plusieurs lignes

q Exemple
DECLARE
entree VARCHAR2(50);
etat INTEGER := 0;
age NUMBER(3);
BEGIN
DBMS_OUTPUT.ENABLE;
DBMS_OUTPUT.PUT_LINE('Entrez votre age’);
DBMS_OUTPUT.GET_LINE(entree, etat);
age := TO_NUMBER(entree);
DBMS_OUTPUT.PUT_LINE('Vous avez donc ' || age || ' ans!'); 16
END;
Les Structures de contrôle dans
PL/SQL

Cours PL/SQL - sonia.guehis@u-paris10.fr 17


Les Structures conditionnelles IF
• Syntaxe :
IF condition THEN
Instructions…
ENDIF;

Ex1: Augmentation du salaire de 15% si la date est postérieure au 09/09/2015


IF date > ’09/09/2015’ THEN
salaire:=salaire*1,15;
END IF;

• Imbrication de plusieurs conditions :


Ex2 : Augmentation du salaire de 15% de l’employé ‘Duval’ si la date est
postérieure au 09/09/2015

IF date> ’09/09/2015’ THEN


IF employé='Duval' THEN.
salaire:=salaire*1,15;
END IF;
END IF;
18
Les Structures conditionnelles IF THEN
ELSEIF
l Objectif : Test de plusieurs conditions
• Syntaxe :
IF <condition> THEN
<instruction(s)>
ELSIF <condition> THEN
<instruction(s)>
ELSIF <condition> THEN
<instruction(s)>
...
END IF;

•Ex : Augmentation du salaire de 15% de l’employé ‘Duval’, de 10% de


l’employé ‘Martin’ et de 5% pour les autres :

IF employé='Duval' THEN
salaire:=salaire*1,15;
ELSIF employé='Martin' THEN
salaire:=salaire*1,10;
ELSE
19
salaire:=salaire*1,05;
END IF;
Structure conditionnelle CASE
l Objectif : Test de plusieurs conditions
l La Différences avec IF-THEN-ELSE:
- Test de plusieurs valeurs en une seule construction
- Définition de la valeur d’une variable

• Syntaxe :

CASE variable
WHEN <expression 1> THEN <valeur 1>
WHEN <expression 2> THEN <valeur 2>

... THEN <valeur n>


END;

Cours PL/SQL - sonia.guehis@u-paris10.fr 20


Exemple Case
• Exemple: Affichage du club de football en fonction du nom de la ville
(Grenoble – GF38 , Marseille – OM, ..., autre – pas d’équipe) :

Declare
club varchar2(10);
ville footballer.town%type;
BEGIN
select town into ville from footballer where id=200;
club:=CASE ville
WHEN 'Grenoble' THEN 'GF38’ ;
WHEN ‘Paris’ THEN ‘PSG’;
ELSE 'Pas d’équipe'
END;
dbms_output.put_line(‘le club est: ’ || club);
END;

Remarque :
dbms_output.put_line(chaîne de caractères) => l’affichage en SQL 21
Structures Itératives : Loop
• Objectif : Exécution à plusieurs reprises d’un groupe d’instructions
• Syntaxe :
LOOP
<instructions>
End LOOP;
• Ex : Incrémenter jusqu’à la valeur 10 un nombre initialisé à 0:
Declare
val number;
BEGIN
val:=0;
LOOP
val:=val+1;
IF (val=10) THEN
EXIT;
END IF;
END LOOP;
22
END;
Structure itérative : While
l Objectif : Exécution d’un groupe d’instructions jusqu’à vérification d’une
condition
• Syntaxe :
WHILE <condition> LOOP <instruction1>;
...
END LOOP;
•Ex : Incrémenter jusqu’à la valeur 10 un nombre initialisé à 0
Declare
val number;
BEGIN
val:=0;
WHILE var < 10 LOOP
val:=val+1;
END LOOP; 23

END;
Structure itérative : FOR
• Objectif : Itérations d’un groupe d’instructions un certain nombre de fois
• Syntaxe :

FOR <variable d’itération> IN (REVERSE) <borne inf>..<borne sup> LOOP


<instruction1>;
...
END LOOP;

• Exemple : Afficher les valeurs entières de 1 à 5

FOR compteur IN 1..5 LOOP


Dbms_output.put_line(compteur);
END LOOP;

Cours PL/SQL - sonia.guehis@u-paris10.fr 24


Structure itérative : EXIT
• Objectif : Quitter une structure itérative
• Syntaxe :
<structure itérative> LOOP
<instruction1>;
...
EXIT [WHEN <condition>]
END LOOP;
• Exemple : Afficher les valeurs entières de 1 à 5 et interrompre la boucle
si la valeur du compteur est égale à 3
FOR compteur IN 1..5 LOOP
dbms_output.put_line(compteur);
EXIT WHEN compteur=3;
END LOOP; 25
Les Curseurs

26
Les curseurs : définition
l Objectif : Récupération d’un résultat de requête sous forme d’une collection

1- Si le résultat d’une requête retourne un seul enregistrement :


select a,b into x,y from t where clé = 123

2- Si le résultat d’une requête retourne plusieurs lignes ???


Besoin d’un curseur …

• Définition : un curseur est une variable permettant d’accéder à un résultat


de requête SQL représentant une collection (ensemble de n- uplets).

•Le curseur implicite : créé et géré par le SGBD à chaque ordre SQL

•Le curseur explicite : créé et géré par l'utilisateur afin de pouvoir traiter un
SELECT qui retourne plusieurs lignes;

27
Curseur Explicite
l L’utilisation d’un curseur explicite nécessite 4 étapes :

1. Déclaration du curseur

2. Ouverture du curseur: Remplissage en une seule fois par exécution de la


requête

3. Traitements des lignes: Récupération des lignes avec un parcours


séquentiel du curseur par un pointeur logique

4. Fermeture du curseur: Libération de la zone qui devient inaccessible

28
Déclaration de curseur

l Dans la section DECLARE du bloc avec la syntaxe :


l Syntaxe :

CURSOR nom_curseur IS instruction_select ;

• Exemple:
Declare
Cursor dpt IS select ename, sal from emp where dptno = 10;

BEGIN
Instructions…
END ;

29
Ouverture d'un curseur
• 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 ;

• Conséquences :
ü Allocation mémoire du curseur
ü Analyse de l'instruction SELECT
ü Positionnement des verrous éventuels (dans le cas SELECT ... FOR UPDATE)

30
Traitement des lignes
• Après l'exécution du SELECT, les enregistrements retournés sont
traités un par un:
FETCH nom_curseur INTO liste_variables

• La valeur de chaque colonne du SELECT doit être stockée dans une


variable réceptrice.

• FETCH ramène un seul enregistrement à la fois

• Pour traiter n lignes, prévoir une boucle

• Après le traitement des lignes, pour libérer la place mémoire: fermer le


curseur:
CLOSE nom_curseur ;

31
Exemple
But: Insérer dans une table Résultat( nom, salaire) les salariés du département 10 dont
le salaire est supérieur à 2500 et inférieur à 5000

Declare
Curosor dpt_10 IS select ename, sal FROM emp WHERE deptno=10 ORDER BY sal ;
nom emp.ename%TYPE ;
salaire emp.sal%TYPE ;

BEGIN
OPEN dpt_10 ;
LOOP
FETCH dept_10 INTO nom, salaire ;
IF salaire > 2500 THEN
INSERT INTO resultat VALUES (nom, salaire) ;
END IF;

EXIT WHEN salaire = 5000 ;


END LOOP ;

CLOSE dpt_10 ;
END; 32
Attributs dans les curseurs
Indicateurs sur l’état d’un curseur :
• %FOUND :
- booléen VRAI si un n-uplet est trouvé

• %NOTFOUND :
- booléen VRAI après la lecture du dernier n-uplet

• %ISOPEN :
- booléen VRAI si le curseur est actuellement actif

• %ROWCOUNT :
- numérique, retourne le nombre de n-uplets dans le curseur

33
Curseur Paramétré
l Pour déclarer un curseur paramétré, dans un même bloc PL/SQL :

DECLARE

CURSOR nom_c (par1 type, par2 type,...) IS ordre_select;

BEGIN

OPEN nom_c(val1, val2,...) ;


…..
END ;

• Type : char, number, date, boolean SANS spécifier la longueur

• Passage des valeurs des paramètres à l'ouverture du curseur

34
Exemple
But: Insérer dans une table résultat ( numero, nom, salaire) les employés
ayant les salaires les plus élévés.

DECLARE

CURSOR c1(psal number) IS


SELECT empno, ename, salaire FROM emp WHERE salaire = psal;
max-sal float;

BEGIN
Select max(salaire) into max-sal from emp;

FOR employe In c1(max-sal) LOOP


Insert into resultat VALUES ( employe.empno,
employe.ename , employe. sal ) ;

END LOOP;
END; 35
Déclaration de Current of
Objectif :
• Modification via SQL sur le n-uplet courant
• Permet d'accéder directement en modification ou suppression du nuplet
récupéré par FETCH

• Syntaxe (pour un curseur c) :

CURSOR nomCurseur ... FOR UPDATE


... <opération> WHERE CURRENT OF nomCurseur

• Remarques :
ü Ne pas oublier de déclarer « FOR UPDATE »
ü Il faut au préalable réserver les lignes lors de la déclaration du
curseur par un verrou d'intention :
(SELECT ... FOR UPDATE [OF nom_colonne,...] ).

36
Exemple

Ex1 : Augmenter les employés dont le salaire est supérieur à 1500 €

DECLARE
CURSOR c1 IS SELECT ename, sal FROM emp FOR UPDATE OF
sal ;

BEGIN
FOR c1_rec IN c1 LOOP
IF c1_rec.sal > 1500 THEN
INSERT INTO resultat VALUES (c1_rec.ename, c1_rec.sal *
1.3);
UPDATE emp SET sal = sal * 1.3 WHERE CURRENT OF c1;
END IF;
END LOOP;
END;

37
Exemple 2

Ex2 : Augmentation de salaire des employés peu rémunérés (employés


dont le salaire est inférieur à 1500 €)

DECLARE
CURSOR c IS SELECT * FROM emp FOR UPDATE;

BEGIN
FOR e IN c LOOP
IF e.salaire < 500.0 THEN
UPDATE emp SET salaire=salaire*1.2 WHERE CURRENT
OF c;
END IF;
END LOOP;
END;

38

Vous aimerez peut-être aussi