Vous êtes sur la page 1sur 29

PL/SQL

PROGRAMMER 
EN PL/SQL

R. Amore

2005
Table des matières

Première partie: le langage................................................................................................................3
 INTRODUCTION                                                                                                                                                           
 
..........................................................................................................................................................    
 3
 
ENVIRONNEMENT                                                                                                                                                        
 
......................................................................................................................................................    
 3
Architecture PL/SQL..............................................................................................................................................3
PL/SQL dans le SGBDR........................................................................................................................................4
PL/SQL dans les Outils ORACLE.........................................................................................................................4
 
STRUCTURE D'UN BLOC                                                                                                                                             
 
...........................................................................................................................................    
 5
 
VARIABLES                                                                                                                                                                    
 
..................................................................................................................................................................    
 6
Définition des variables PL/SQL...........................................................................................................................6
Exemples de déclarations de variables...................................................................................................................6
Affectations des variables sous PL/SQL................................................................................................................6
Validité et visibilité des variables dans les blocs imbriqués..................................................................................7
 
TRAITEMENTS  CONDITIONNELS                                                                                                                            
 
..........................................................................................................................   
 8
Exemple d'utilisation des traitements conditionnels..............................................................................................8
 
TRAITEMENTS REPETITIFS                                                                                                                                        
 
......................................................................................................................................
   
 9
Boucle  LOOP .......................................................................................................................................................9
Boucle FOR............................................................................................................................................................9
Boucle WHILE.....................................................................................................................................................10
 
LES CURSEURS EN PL/SQL                                                                                                                                       
 
.....................................................................................................................................    
 11
Curseur Implicite:.................................................................................................................................................11
Curseur Explicite:.................................................................................................................................................11
Etapes d'utilisation d'un curseur Explicite............................................................................................................11
Déclaration de curseur:.........................................................................................................................................11
Ouverture / Fermeture..........................................................................................................................................12
Traitement des lignes:...........................................................................................................................................12
%Found.................................................................................................................................................................13
%NotFound...........................................................................................................................................................14
%IsOpen...............................................................................................................................................................14
%RowCount..........................................................................................................................................................15
%RowType............................................................................................................................................................15
Boucle et Curseur.................................................................................................................................................16
Curseur paramétré.................................................................................................................................................16
Exemple d'utilisation des curseurs........................................................................................................................17
 
GESTION DES ERREURS                                                                                                                                            
 
..........................................................................................................................................    
 19
Erreurs ORACLE..................................................................................................................................................19
Liste des exceptions predefinies...........................................................................................................................20
Initialisation d'erreurs...........................................................................................................................................20
 
UTILISATION DE FONCTIONS EN PL/SQL                                                                                                             
 
...........................................................................................................
    
 21
 
FONCTIONS UTILISABLES EN PL/SQL                                                                                                                   
 
.................................................................................................................
    
 22
Fonctions sur chaînes et caractères......................................................................................................................22
Fonctions sur Nombres:........................................................................................................................................22
Fonctions sur dates:..............................................................................................................................................22
Fonctions de conversion.......................................................................................................................................23
Fonctions diverses................................................................................................................................................23
DEUXIEME PARTIE: PROCEDURES, FONCTIONS, TRIGGERS........................................24
 PRINCIPES, DEFINITIONS                                                                                                                                        
 
.......................................................................................................................................    
 24
 
PROCEDURES ANONYMES ET STOCKEES                                                                                                            
 
..........................................................................................................
    
 24
Initialisation de variables hôtes dans les procédures:..........................................................................................25
Passages de paramètres dans les procédures........................................................................................................26
 
FONCTIONS                                                                                                                                                                  
 
................................................................................................................................................................    
 26
 
TRIGGERS                                                                                                                                                                     
 
...................................................................................................................................................................    
 27
Exemple................................................................................................................................................................27
Généralités ­ Définitions......................................................................................................................................27
Triggers et procédures stockées............................................................................................................................28
Triggers par ordre et triggers ligne.......................................................................................................................28
Restrictions...........................................................................................................................................................28
R.Amore Page 2
R.Amore Page 3
Première partie: le langage

 I N T R O D U C T I O N 

PL/SQL est un langage au même titre que SQL

Tout comme SQL, PL/SQL peut être utilisé au sein d'outils comme : SQL*Plus, SQL*FORMS, PRO*,...

Pourquoi utiliser PL/SQL ?

SQL est un langage de requêtes complet pour travailler sur la base de données, mais non procédural.

PL/SQL comprend :

­ La partie LID de SQL (Select)
­ La partie LMD de SQL (Update, Insert, Delete)
­ La gestion des transactions (Commit, Rollback, Savepoint..)
Plus:
­ Presque tous les outils (instructions) d’un langage procedural (variables, instructions alternatives et 
itératives, ...)
­ Curseurs : Declare, Fetch, Close
­ Fonctions : To_Char, To_Date, Upper, Substr, Round,...

Le PL/SQL intègre tous les avantages du SQL, plus une partie procédurale (If, While,For,...) ainsi que 
des mécanismes de communication clients­serveurs.
Boucles
Loop, For, While, exit [When].
Conditions
If, Then, Elsif, Else, End if
Affectations
prix_f_fr := prix_$* :taux
nom :=Upper (nom)

 E N V I R O N N E M E N T 
Architecture PL/SQL
Fonctionnement
PL/SQL interprète des blocs de commandes.
==> gain de temps sur les transmissions
==> gain de performances
SQL et PL/SQL ont tous deux un "moteur" associé :
­ SQL statement executor
­ Procedural statement executor
Le moteur SQL se trouve avec le noyau RDBMS
Le moteur PL/SQL se trouve :
­ Soit avec le noyau RDBMS
­ Soit avec l'outil (Sql*Plus, Sql*Forms, ...)

R.Amore Page 4
Différents environnements PL/SQL

PL/SQL  est utilisable dans le SGBDR

Utilisable avec :
­ précompilateurs (v.1.3) ex: Pro*C
­ SQL*Plus (>= v.3)
­ SQL*DBA (V.6.0)

PL/SQ L  da ns  le s  Ou t ils   OR AC LE

Utilisable avec :
­ SQL*Forms (v.3)
­ SQL*Menu,
­ SQL*ReportWriter

On dispose donc d'un langage procédural au sein de l'outil et d'une approche algorithmique au niveau 
Trigger, par exemple.

R.Amore Page 5
 S T R U C T U R E   D ' U N   B L O C 

Un Bloc 

PL/SQL n'interprète pas une commande, mais un ensemble de commandes contenu dans un "bloc" PL/SQL

Structure du bloc :

DECLARE
Déclarations de variables, constantes, exception

BEGIN
Section obligatoire
Intructions SQL et PL/SQL
Possibilité de bloc fils (imbrication de bloc)

EXCEPTION
Traitement des exceptions (gestion des erreurs)

END ;

Chaque instruction, de n'importe quelle section, se termine par  " ; "

==> plus grande lisibilité des programmes, simplification des traitements complexes. 

Exemple de bloc PL/SQL
Declare
Numero_stock Number (5);
Begin
Select Quantité Into Numero_stock From Inventaire
Where Produit =" RAQUETTE DE TENNIS";
/* Contrôler que le stock soit suffisant */
If numero_stock > O Then
Update inventaire Set quantité = quantité ­ 1
Where produit ="RAQUETTE TENNIS";
Insert Into achat
Values ("RAQUETTE TENNIS ACHETE." ,SYSDATE);
Else
Insert Into purchase_record
Values ("PLUS DE RAQUETTE DE TENNIS", SYSDATE);
End if ;
Commit;
End;

R.Amore Page 6
 V A R I A B L E S 

PL/SQL donne la possibilité d'utiliser des variables.

Variables de  type O RACLE :


Char 
Number 
Date (DD­MON­YY)
Ces variables pourront faire référence au dictionnaire de données
Variables de  types booléen (vrai ou faux).

Variables définies  dans l'env ironnement ex térieur au bloc PL/ SQL


­champs de l'écran en SQL*FORMS
­variables définies dans le langage hôte dans PRO*
Ces variables seront utilisées, préfixées de " : "

Définition des variables PL/SQL

* Les variables se définissent dans la partie Declare du bloc PL/SQL
* On peut faire référence à une colonne d'une table par la variable 
Table.Colonne%TYPE
* On peut faire référence à une ligne d'une table par variable Table%ROWTYPE
* On peut faire référence au type d’une variable précédemment définie par variable 
Nom_Var%TYPE
* L'attribut "constant" permet de figer l'affectation d'une variable
* l'attribut "not null" interdit les valeurs nulles
==> obligation d'initialiser la variable lors de sa définition
* l'initialisation d'une variable se fait par l'opérateur ":=" suivi d'une
­ constante,
­ d'une expression PL/SQL
­ d'une fonction PL/SQL

Exemples de déclarations de variables

DECLARE

Total Number(9,2);
Nom Char(10):="MILLER";
Longueur  Number Not Null := Length (NOM)* 2;
Date_emb Date;
PI  Constant Number :=3.14,  /* Ne pourra plus varier */
Debut Number Not Null := 1000;
Numero Emp.Empno%TYPE;
Depart Dept%ROWTYPE ;
Prenom Nom%TYPE ;

R.Amore Page 7
Affectations des variables sous PL/SQL

Utilisation

Il existe deux moyens d'affecter une valeur à  une variable :
­ l'opérateur :=
­ l'ordre select ... into (voir chapitre sur les curseurs)

L'opérateur ":=" constante

nom_var := expression ou fonction (voir chapitre sur les fonctions)

Exemple:
prix:= 100;
prix:= Anc_Prix*1.1;
prix:= prix + taxe
prix:= round(prix_total); 

L'ordre Select...into :
select colonne into variables from table;
(Si le select ramène plusieurs lignes, utilisation obligatoire d'un curseur)

Exemple :
Select Sal Into Salaire From Emp
Where Ename = 'SMITH';

Val i d i t é   et   v i s i b i l i t é  d e s  va ri ab l e s   d an s   l es   b l o cs   i m b ri q u é s

Declare
Compte  Number(5);
Credit_max    Number(9,2);
Begin
­­Variables utilisables: Compte (Number),Credit_max
­­Sous bloc 1
Declare
Compte Char(20);
Balance1  Number(9,2);
Begin
­­Traitement
­­Variables utilisables : Credit_max, Compte(Char), Balance1
End;

­­Traitement

­­Sous bloc 2
Declare
Balance2 Number(9,2);
Begin
­­Traitement
­­Variables utilisables : Compte(Number) Credit_max, Balance2
End;
­­Variables utilisables : Compte (Number) Credit_max
End;

R.Amore Page 8
 T R A I T E M E N T S     C O N D I T I O N N E L S 
Permettent de contrôler le moment où des instructions seront exécutées.

S y n t a x e    :

If (Condition) Then
traitement
[Else / Elsif (Condition)]
traitement
End if;

Variable       ou Opérateur Variable     ou


Avec :  Condition = Constante Constante

Les opérateurs sont les mêmes que dans SQL 
(=, <, >, !=, <=, >=, <>, Is Null, Is Not Null..)
­ Else est utilisé si les instructions qui suivent ne possèdent pas de conditions.
­ Elsif, si les instruction qui suivent possèdent des conditions.

Exemple d'utilisation des traitements conditionnels

Declare
Job Char ( 10);
Nom Char 11 5) :='MILLER';
Mess Char (30);

Begin
Select Job Into Job From Emp Where Ename = NOM;

If Job Is Null Then
Mess := Nom|| ' n ''a pas de job';
Insert Into Resultat Values (Null, Null, Mes);
Elsif JOB = 'SALESMAN' Then
Update Emp Set Comm = 1000 Where Ename = Nom;
Mess := Nom|| ' Commission modifiée';
Insert Into Resultat Values (Null, Null, Mes);
Else
Update EMP Set Comm = 0 Where Ename = Nom;
Mess := Nom|| 'pas de commission';
Insert Into Resultat Values (Null, Null, MES);
End If;
Commit;
End;

R.Amore Page 9
 T R A I T E M E N T S   R É P É T I T I F S 

PL/SQL offre la possibilité d'effectuer des traitements répétitifs grâce à l'opérateur LOOP

Boucle  LOOP .

S y n t a x e  :

Loop [Label]
Instructions
End Loop [Label];
La commande EXIT nous permettra de sortir de la boucle.

Exemple:
Declare
Nbre Number;
Begin
Nbre := O;
Loop
Nbre := Nbre + 1;
If Nbre >10 Then Exit;
End if;
End Loop;
End;

Boucle FOR

S y n t a x e  :

For Var In [Reverse] Var_Debut .. Var_fin Loop
  Instructions
End Loop;

­ Var est obligatoirement une variable (définie en DECLARE)
­ Var_debut et Var_fin peuvent être des variables ou des constantes.
­ Le pas d'incrément est de 1.

Exemple:

Begin

For I In 1 .. 5 Loop 
Insert Into Resultat Values (l, Null, 'EXTERIEUR');
<<Label2>>
For J In 1 .. 10 Loop
Insert Into Resultat Values (NULL, J,' '||'INTERIEUR');

R.Amore Page 10
End Loop;
End Loop;
End;

Boucle WHILE

S y n t a x e  :

While (Condition)
Loop
Instructions
End Loop;
­ condition est une combinaison d'expressions logiques réalisées au moyen des opérateurs:<,>, =, !=, 
<=, >=, AND, OR ...

Exemple:

Declare
Salaire Emp.Sal%TYPE;
Manager Emp.Mgr%TYPE;
Nom Emp.Ename%TYPE;
Num_debut Constant Number (4) := 7902;

Begin
Select Sal, Mgr,Ename Into Salaire, Manager Nom From Emp
Where Empno < Num_debut;

While Salaire < 4000 Loop
 Select  Sal, Mgr, Ename Into Salaire, Manager, Nom From Emp Where Empno = Manager;
 ...
End Loop;
...
Insert Into Resultat Values (Null, Salaire, Nom);
Commit; 
END;

R.Amore Page 11
 L E S   C U R S E U R S   E N   P L / S Q L 

C’est une zone mémoire de taille fixe, utilisée par le noyau pour analyser et interpréter tout ordre SQL.
Les statuts d'exécution de l'ordre se trouvent dans le curseur.

LES DIFFERENTS CURSEURS

Curseur Implicite:

– Généré et géré par le noyau pour tout ordre SQL.
– Utilisation totalement transparente

Curseur Explicite:

­ créé et géré par l'utilisateur pour traiter un ordre select qui ramène plusieurs lignes.
==>Le traitement des lignes ramenées par le Select se fait ligne à ligne (en particulier : Fetch).

Etapes d'utilisation d'un curseur Explicite

L'utilisation d'un curseur pour traiter un ordre select ramenant plusieurs lignes, nécessite 4 étapes:
­ Déclaration du curseur
­ Ouverture du curseur
­ Traitement des lignes
­ Fermeture du curseur.

Déclaration de curseur:

­ Permet de stocker l'ordre select dans le curseur.
S y n t a x e  :
­ Se définit dans la partie DÉCLARE du block PL/SQL.

DECLARE
CURSOR nom_curseur IS ordre_select;

Exemple:
Declare
Cursor Dept_10  Is
Select Ename, Sal From Emp Where Deptno = 10;

R.Amore Page 12
Ouver ture / Fermeture

OUVERTURE DU CURSEUR:
entraine:
­ allocation mémoire du curseur.
­ analyse sémantique et syntaxique de l'ordre.
­ positionnement de verrous éventuels (si l’on utilise select for update...).

FERMETURE DU CURSEUR:
­ libération de la place mémoire.
S y n t a x e  :
­ dans la partie traitement du bloc PL/SQL.
­ avoir préalablement déclaré le curseur pour l'ouvrir
­ avoir préalablement ouvert le curseur pour le fermer.

Begin
Open nom_curseur;
     /* ....TRAITEMENT DES LIGNES .......*/
Close nom_curseur;

Exemple:

BEGIN
Open dept_10;
/*.......TRAITEMENT DES LIGNES .........*/
Close dept_10;

Tr a i t e m e n t   d e s   l i g n e s :

­ traiter les lignes une par une.
­ renseigner les variables réceptrices définies dans la partie déclare du bloc.

S y n t a x e  :
­ dans la partie traitement du bloc PL/SQL.
­ avoir préalablement ouvert le curseur.
FETCH Nom_Curseur INTO Liste variables

L'Ordre Fetch ne ramène qu'une ligne à la fois
==> nécessité de recommencer l'odre pour traiter la ligne suivante.

Exemple:

Begin
Open dept_10;
Loop
Fetch dept_10 Into nom, salaire;
/*........TRAITEMENT LIGNE..... */
End Loop;

R.Amore Page 13
Les informations quant à l'exécution de l'ordre, sont conservées par PL/SQL après chaque exécution de 
curseur (explicite ou implicite)
Ces informations permettent de tester directement le résultat de l'exécution

UTILISATION

Pour un curseur implicite, par les variables prédéfinies:
­ SQL%FOUND
­ SQL%NOTFOUND
­ SQL%ISOPEN
­ SQL%ROWCOUNT

Pour un curseur explicite, par les variables prédéfinies:
­ Nom_Curseur%FOUND
­ Nom_Curseur%NOTFOUND
­ Nom_Curseur%ISOPEN
­ Nom_Curseur%ROWCOUNT
­ Nom_Curseur%ROWTYPE

%Found
Type : Booléen.
­ Curseur implicite: ­ si VRAI ==> Update , Insert , Delete : traite au moins 1 ligne.
­ Curseur explicite ­ si VRAI ==> Le Fetch ramène au moins 1 ligne.

Exemple:

Declare
Cursor num1_cur Is Select num From num1_tab
Order by sequence;
Cursor num2_cur Is Select num From num2_tab
Order by sequence;
num1  Number;
num2  Number;
pair_num  Number :=O;
Begin
Open num1_cur;
Open num2_cur;
Loop
Fetch num1_cur Into num1;
Fetch num2_cur Into num2;
If (num1_cur%FOUND) and (num2_cur%FOUND) Then
pair_num := pair_num + 1;
Insert Into sum_tab Values (pair_num, numl + num2);
Else 
Exit;
End If;
End Loop;
Close num1_cur;
Close num2_cur;
End;

R.Amore Page 14
%NotFound
Type :  Booléen.
Curseur implicite: Insert 
si VRAI ==> Update  ne traite aucune ligne.
Delete 
Curseur explicite: si VRAI == > Le Fetch ne ramène plus de ligne.

Exemple:

Declare
Cursor num1_cur Is Select num From numl_tab
Order by sequence;
Cursor num2_cur Is Select num From num2_tab
Order by sequence;
num1  Number;
num2  Number;
pair_num Number := O;
Begin
Open numl_cur;
Open num2_cur;
Loop
Fetch num1_cur Into num1;
Fetch num2_cur Into num2;
Exit When (num1 cur%NOTFOUND) OR (num2_cur%NOTFOUND);
pair_num := pair_num + 1;
Insert Into sum_tab Values (pair_num, num1 + num2);
End Loop;
Close num1_cur;
Close num2_cur;
End;

%IsOpen
type : Booléen;

Curseur implicite: toujours FAUX, car Oracle referme les curseurs qu'il ouvre après chaque utilisation.
Curseur explicite: si  VRAI ==> le curseur est ouvert.

Exemple:
Declare
Cursor Dept_10 Is
Select Ename, Sal From Emp Where Deptno = 10;
Begin
If Not (Dept_10%1sOpen) Then Open Dept_10;
End If;
Fetch Dept_10 Into ...
/* ­­TRAITEMENT­­ */
End

R.Amore Page 15
%RowCount
type : Numérique.
­ Curseur implicite: Nombre de lignes traitées par l'ordre ==> Update, Insert, Delete
­ Curseur explicite:  incrémenté à chaque ordre Fetch. Il traduit la Nième ligne traitée.

Exemple:
Declare
Cursor C1 is 
Select ename, empno, sal From emp 
Order by sal Desc;
nom Char ( 10);
numero Number (4); 
salaire Number (7,2);
Begin
Open c1;
Loop
Fetch C1 Into nom, numéro, salaire;
Exit When (C1%ROWCOUNT > 25) Or (C1%NOTFOUND);
Insert Into temp Values (salaire, numéro, nom);
Commit;
End Loop;
Close C1;
End;

% R o w Ty p e
Déclaration implicite d'une structure dont les éléments sont d'un type identique aux colonnes de la table 
de la base ramenées par le curseur.

S y n t a x e    :   d a n s   l a   p a r t i e   d é c l a r a t i o n   d u   b l o c .

Declare
Cursor nom_curseur Is <ordre_Select>;
nom_record nom_curseur%ROWTYPE;
­ les éléments de la structure sont identifiés par : nom_record.nom_colonne
­ la structure est renseignée par le Fetch : Fetch nom_curseur Into nom_record;

Exemple
Declare
Cursor C1 Is Select sal + NVL (comm, O) saltot, ename
From emp;
C1_rec  C1%ROWTYPE;
Begin
Open c1;
Loop
Fetch C1 Into C1_rec;
Exit When C1 %NOTFOUND;
If c1_rec.saltot > 2000 Then
Insert Into temp Values (null, c1_rec.saltot, c1_rec.ename);
End If;
End Loop;
Close C1;
End;
R.Amore Page 16
Boucle et Curseur

F O R . . . I N . . . L O O P. . . "

Utilité :
­ faciliter la programmation des boucles avec curseur.

UTILISATION

Syntaxe

Declare
Cursor <Un_Nom>_cursor (dnum Number) Is
Select ....... Where deptno=dnum;
Begin
............
For <UnNom>_record In <UnNom>_cursor Loop /* Nbre d'itérations = Nbre de lignes ramenées */
............ /* Ouverture implicite du curseur */
/*  TRAITEMENT  */ /* Génération implicite d'une variable de type
/* %ROWTYPE  :  <UnNom>_record (non déclarée) */
End Loop; /* Paramétrage possible du curseur  (cf page suivante) */

Exemple
Declare
Cursor emp_cursor Is Select comm, ....;
Begin
Open emp_cursor;
For emp_record In emp_cursor Loop
Fetch emp_cursor Into emp_record;
Exit When emp_cursor%NOTFOUND:
...... /*  TRAITEMENT  */
End Loop;
Close Emp_cursor;
Commit;
La déclaration de emp_rec est locale à la partie traitement du bloc.

Curseur paramétré

POURQUOI ?

utiliser des variables dans le curseur (principalement dans la clause WHERE) et créer ainsi des curseurs 
paramétrés.

UTILISATION 

spécifier les noms et types des paramètres dans la déclaration du curseur.

R.Amore Page 17
Syntaxe

Declare
Cursor nom_curseur (para_1 type, para_2 type ...)
Is ordre_select ... where (champ1 = para_1 and champ2 < para_2;
 /* On utilise ici, les paramètres dans le Where */
Type des paramètres: Char, Number, Date, Boolean (sans préciser la longueur).
Intérêt : passer la valeur des paramètres à l'ouverture du curseur. 

Begin
Open nom_curseur (val1, val2,...);

Exemple :
Declare
Cursor c1 (depart Number)
Is Select sal, nvl (comm, O) commi From emp
Where deptno = depart;
total Number(11,2) := 0;
sal_sup Number(4) := 0;
comm_sup Number(4) := 0;
Begin
For c1_rec In c1 (20) Loop /* 20 est la valeur du paramètre effectif, et c1_rec la */
total := total + c1_rec.sal + c1_rec.commi; /* variable implicitement déclarée pour le curseur c1 */
If c1_rec.sal>2000.00 Then
sal_sup := sal_sup + 1;
End If;
End Loop;
Insert Into temp Values (sal_sup, comm_sup,'Total Salaire' To Char (total));
Commit;
End;

Exemple d'utilisation des curseurs
LA CLAUSE "CURRENT OF..."

POURQUOI ?

­ accéder directement à la ligne ramenée par l'ordre fetch afin de la traiter (Update, Delete).
UTILISATION

­ se réserver la ligne lors de la déclaration du curseur par le positionnement d'un verrou d'intention, par 
un For Update Of nom_col (obligatoire, sinon il en résulte une erreur).
­ spécifier que l'on veut traiter la ligne courante au Fetch par la clause: ".. Where Current of 
nom_curseur";
Ex:   Declare
Cursor c1 Is select ename, sal from emp for update of sal;
Begin
For c1_rec In cl Loop
If c1_rec.sal>1500 Then
Insert Into Resultat Values (c1_rec.sal, c1_rec*1.3, c1_rec.ename);
Update Emp Set Sal = Sal * 1.3 Where Current Of cl;
End If;
End Loop;
End;
R.Amore Page 18
 G E S T I O N   D E S   E R R E U R S 

Affecter un traitement approprié aux erreurs apparues lors de l'exécution du bloc PL/SQL. Ce traitement 
est obligatoirement à effectuer lors de l'apparition d'un évènement anormal.
Distinguer 2 types d'erreurs:
­ erreur interne oracle (SQLCODE != O) : la main est directement rendue au système environnant.
­ anomalie déterminée par l'utilisateur (User defined Exception)

SOLUTIONS
­ Donner un nom à l'erreur (Si elle n'est pas déjà définie en interne).
­ Définir les anomalies utilisateur, leur associer un nom.
­ Définir le traitement à effectuer.

UTILISATION

­ nommer l'anomalie (utiliser le type Exception) dans la partie déclare du bloc :
Declare
nom_ano EXCEPTION; /* Déclaration indispensable seulement si Exception Utilisateur */
­ définir l'anomalie, et passer la main au traitement approprié (Raise 6 "Provoquer").
Begin
If (anomalie) Then 
Raise nom_ano;
/*  effectuer le traitement défini dans la partie EXCEPTION du bloc. */
Exception
When nom_ano Then
/* traitement */;
End;

Exemple

Declare
pas_comm Exception;
salaire Emp.Sal%TYPE;
commi Emp.Comm%TYPE;
numéro Emp.Empno%TYPE;
Begin
Select Sal, Comm, Empno Into salaire, commi, numero
From Emp Where Empno = :num_emp;
/*  :num­emp fait référence à une variable extérieure au bloc pl/sql ­*/
If commi = O or commi Is Null Then
Raise pas_comm;
Else
... (traitement)...
End If;
Exception
When pas_comm Then
Insert Into Resultat Values (numéro, salaire, 'pas de commission');
End;

R.Amore Page 19
Err e u r s  OR AC LE

FONCTIONNEMENT

Lors de l'apparition d'une erreur ORACLE à l'exécution, deux possibilités:
­ retour immédiat au système environnant, si pas de traitement spécifique dans la partie Exception du 
bloc.
­ exécution du traitement associé, si spécifié dans la partie Exception du bloc.
REGLES
­ pour être exécuté, le traitement d'erreur doit porter le nom de l'erreur (et non son code).
­ les principales erreurs sont ainsi déjà prédéfinies.

Exemples:

Begin
Insert Into Dept Values (numéro, nom, ville);
Exception
When DUP_VAL_ON_INDEX Then .
Insert Into Erreur Values (numéro, 'déjà inséré');

Liste des exceptions predefinies

Si les codes d'erreurs sont déjà nommés dans PL/SQL.
==> Pas d'association à faire dans la partie Declare du bloc.

DUP_VAL_ON_INDEX ­1 INVALID_CURSOR ­1001


INVALID_Number  ­1722 LOGIN_DENIED ­1017
NO_DATA_FOUND ­100 NO_LOGGED_ON  ­1012
PROGRAM_ERROR ­6501 STORAGE_ERROR ­6500
TIMEOUT_ON_RESOU ­5l TOO_MANY_ROWS ­1427
RCE
VALUE_ERROR ­6502 ZERO_DIVIDE ­1476
OTHERS TOUTES LES AUTRES 
­­> ERREURS NON 
EXPLICITEMENTS NOMMEES

Initialisation d'erreurs

POURQUOI ?
Permet d'associer un nom à un code erreur oracle (ces codes ne sont pas définis dans PL/SQL). C’est le 
seul moyen de traiter les erreurs internes à Oracle.

COMMENT?

Dans la partie déclaré du bloc :
PRAGMA EXCEPTION_INIT (nom_exception, code_erreur);
­ nom_exception : Référence à une exception précédemment définie.
­ code_erreur : Référence à un code d'erreur Oracle valide..
R.Amore Page 20
Declare
fetch_out_of  EXCEPTION;
PRAGMA EXCEPTION_INIT (fetch_out_of, ­1002); /* ­1002 est le N° de l’erreur interne à Oracle */
Begin
/*Traitement */ ...
Exception
When Fetch_Out_Of Then
/* TRAITEMENT DE L'ERREUR */;
End;

R.Amore Page 21
 U T I L I S A T I O N   D E   F O N C T I O N S   E N   P L / S Q L 

POURQUOI ?

Affectation à une variable du résultat renvoyé par une fonction.
Utilisation de toutes les fonctions SQL, directement, sans faire d'accès à aucune table.
Fonctions propres à PL/SQL.

Declare
LG Number;
MESS Char (40);
Begin
Mess:= 'Quelle est la longueur de la chaîne ?';
LG := Length (MESS);
Insert Into Resultat Values (LG, NULL, MESS);
Commit;
End;

SQLCODE    ­>Number : renvoie le code de l'erreur courante.
SQLERRM [(CODE ERREUR)]    ­>Char
Si le code erreur n'est pas spécifié, la fonction renvoie le message du code erreur courant.

Exemple:

Declare
NOM Char (10);
Code  Number;
LG Number;
Mess Char (50);
Begin
Select Ename Into Nom From Emp Where Empno = 9999;
Exception
When Others Then
Code:= SQLCODE;
Mess:=  SQLERRM;
Lg := LENGTH(MESS);
Insert Into Resultat Values (CODE, LG, MESS);
Commit;
End;

R.Amore Page 22
 F O N C T I O N S   U T I L I S A B L E S   E N   P L / S Q L 
Toutes les fonctions utilisées en  SQL sont valides en PL/SQL.

Fonctions sur chaînes et caractères

Fonction Type  Exemple


renvoyé
Ascii(Chaine) Nombre Ascii ('ABCD')   65.
Chr(Nombre) Char Chr (65)  'A'.
Initcap (Chaine) Char Initcap ('marTlN')   'Martin'
Instr (Chaine,Ss_Chaine[,Pos[,n] Nombre Instr ('ADAMS','A',1,2)   3
Length (Chaine) Nombre Length ('Martin')   6
Lower(Chaine) Chaine Lower ('marTlN')   'martin'
Upper (Chaine) Chaine Upper ('marTlN')   'MARTIN'
Lpad (Chaine,Lg[, Char] Chaine Lpad ('Martin', 10 ' * ')   ' * * * *Martin
Rpad (Chaine,Lg[, Char] Chaine Rpad ('Martin', 10 '*')   'Martin* * * *'
Ltrim (Chaine,Ens_Caract) Chaine Ltrim ('Martin', 'rm')   'artin'
Rtrim (Chaine,Ens_Caract) Chaine Rtrim ('Martin', 'Rm')   'Martin'
Rtrim ('Martin', 'Rn')   'Marti'
Replace (Chaine, Car[, Car_Subst] Chaine Replace ('Adams', 'A', 'AAAA')   'AAAADams'
Replace ('ADAMS', 'A')   'DMS'
Substr (Chaine, Début, Nbre_Car) Chaine Substr ('Martin',2,3)   'art'
Translate (Chaine,Car_Srce,Car_Cible)  Chaine Translate ('Martin', 'am', '*#')   '#*rtin'
Chainel || Chaine Chaine 'Bonjour '||'Martin'   'Bonjour Martin'.

Fonctions sur Nombres:

Fonction Type  Exemple


renvoyé
Abs (n) Nombre Abs (­31.25.)   31.25.
Ceil(n) Nombre Ceil (31.05)   32.
Floor (n) Nombre Floor (12.6)   12.
Floor (­12.6)  ­13.
Mod (n, m) Nombre Mod (7.2)  1.
Power (n, m) Nombre Power (2,3)  8.
Round(n[,m])  Nombre Round ( 1250,­3)    1000.
Round (125.346,2)    125.35.
Sign (n) Nombre Sign (­31 )  ­1     Sign (31)   1      Sign (O)   O
Sqrt(n)  Nombre Sqrt (16)   4
Sqrt (­16)   Null
Trunc(n[,m]) Nombre Trunc (1250,­3)  1000
Trunc (125.346,2)  125.34

Fonctions sur dates:

Fonction Type  Exemple


renvoyé
Add_Months (Date,n) Date Add_Months ('08­JUN­99',3)   '08­SEP­99'
Last_Day (Date)  Date Last_Day ('12­JAN­99')   '31 ­JAN­99
Months_Between (Date1, Date2)  Nombre Months_Between ('14­JUN­99', 01 ­JAN­99')    ­5.41
Next_Day (Date, Nom_Jour)  Date Next_Day ('12­JAN­99','MONDAY')   18­JAN­99
Round(Date[, Format]) Date Round (Sysdate,'MM')   'Ol­JUL­99' (Sysdate : 14­JUL­99)
Round (Sysdate,'MM')   '01­AUG­99' (Sysdate : 16­JUL­99)
Trunc(Date[,Format]) Date Trunc (Sysdate, 'W')   Ol­JAN­99'. (Sysdate :  31­DEC­99)
R.Amore Page 23
Fonctions de conversion

Fonction Type  Exemple


renvoyé
To_Char (Date[,Format]) Chaine To_Char (Sysdate, 'DD/MM/YY')  ' 14/07/99'.
( si Sysdate est le 14­JUL­99)
To_Char (Nombre[, Format]) Chaine To_Char (56.478,'999.99')   56.48 
To_Date (Chaine[, Format]) Date  To_Date ('14/07/99', 'DD/MM/YY')  '14­JUL­99'
To_Number (Chaine) Nombre To_Number ('1234')   1234.

Fonctions diverses

Fonction Résultat obtenu
Greatest(Expres1,Expres2,...ExpresN) Plus grande expression du type de Expres1
(Expres2,.ExpresN seront convertis dans le type de Expres1)
Least (Expres1, Expres2,...ExpresN) Plus petite expression du type de Expres1
Expres2,...ExpresN seront convertis dans le type Expres1)
Uid Numéro d'utilisateur attribué par Oracle à un utilisateur
User Nom courant de l'utilisateur
Decode cf doc.  Sql 
Nvl (Nombre1,Nombre2) Nombre2 si  Nombre1 est Null
Nvl (Chaine,Chaine) Chaine2 si  Chaine1 est Nulle
Nvl (Date1,Date2) Date2 si Date1 est Nulle
Nvl (Booléen1, Booléen2) Booléen2 si Booléen1 est null

R.Amore Page 24
D E U X I E M E   P A R T I E :   P R O C E D U R E S , 
FONCTIONS, TRIGGERS.
 P R I N C I P E S ,   D E F I N I T I O N S 
Une procédure est un ensemble d'instructions PL/SQL et de commandes SQL. On peut utiliser les 
procédures pour plusieurs raisons. Elles permettent de rassembler sous un nom générique, un 
traitement plus ou moins complexe, sans avoir à se préoccuper des détails de ce traitement (sauf à la 
création/mise au point), mais seulement de la nature du traitement. Les deux questions essentielles que 
l'on se posera lors de l'utilisation des procédures seront: que fait elle?, et  comment l'utiliser?
Une fois que la procédure est construite, on peut la considérer comme une boite noire que l'on utilise 
dans un autre bloc en l'appellant simplement par son nom.
Ex: calcul; // appel d'une procédure nommée calcul
Une extension très utilisée des procédures, consiste à généraliser leur usage, en prévoyant l'utilisation 
de paramètres, qu'il faudra préciser lors de l'appel de la procédure. En principe, une procédure ne 
retourne pas de valeur. Son rôle est plutôt d'exécuter un traitement en restant plus ou moins "muette" 
(bien que ce ne soit pas une obligation!).
Ex: calcul(val1, val2) // idem: ici la procédure accepte deux paramètres
//val1 et val2
Si le traitement doit retourner une information (comme pour les fonctions standards SQL ou autres...) il 
faut alors utiliser, metre en oeuvre les fonctions. Une fonction n'est rien d'autre qu'une procédure dans 
laquelle il a été prévu de "retourner" un résultat qui pourra être clairement stocké dans une variable, par 
exemple. Ce qui différenciera une fonction d'une procédure, sera simplement la façon dont elles seront 
appelées dans les fragments de code PL/SQL. 
Ex: Res := Calcul(val1) // On appelle la fonction en lui passant un paramètre val1
// Le résultat du calcul est stocké dans la variable Res.
Enfin, un trigger est constitué par l'ensemble événement/traitement. Un trigger consiste à associer un 
événement à un traitement. Comment? 
Tout d'abord il faut savoir que ce que l'on nomme "événement" correspond à une action bien précise et 
répertoriée (ex: insérer une ligne dans une table, supprimer, ...). Ensuite, il suffit de savoir que cette 
association événement/traitement, se réalise à la création du trigger (create trigger ...). Lorsque tel 
événement surviendra sur telle table, le trigger qui lui aura été associé sera déclenché, et le traitement 
décrit dans la commande de création du trigger sera effectué. Le traitement sera simplement un bloc 
quelconque PL/SQL, voire un simple appel à une ou plusieurs procédures.

 P R O C E D U R E S   A N O N Y M E S   E T   S T O C K E E S 
Une procedure est stockée si elle est déclarée comme ceci (as):
Create Procedure NomProc (param1 Integer, Param2 Char, ...) AS
Begin
  Texte  des traitements, ...
End;
Une procédure peut néanmoins être utilisée et déclarée sans être pour autant stockée dans la base, 
dans tous les outils Oracle qui supportent PL/SQL (tels SQL*Plus, SQL*DBA, ...). 

R.Amore Page 25
Exemple :
Procedure Debit (No_Cpte Integer, Montant Real) IS
  Anc_Bal     Real;
  New_Bal    Real;
  ....déclarations locales à la procédure
Begin
  Select .....
  .....Traitement
Exception
  When .... Then
End Debit;
Elles peuvent être déclarées dans les blocs PL/SQL anonymes, dans les procédures, les fonctions et les 
packages. Elles doivent néanmoins être déclarées à la fin de la section des déclarations. Comme :
Declare
  Var1 Integer;
  Var2 Real;
  ...
  Procedure NomProc ( Param1 Integer, ....) IS // Déclaration de la procédure en fin de 
  Begin // Section Declare
  ... 
  End;
Begin // Puis, début du traitement dans le bloc 
  ... // PL/SQL anonyme
  Traitements
  NomProc (Valeur1, ...); // Appel de la procédure NomProc
  Suite traitements, ...
  NomProc (Valeur1, ...); // Nouvel appel de la procédure NomProc 
  ...
End;
La visibilité de la procédure Nomproc est restreinte à ce bloc local, dans l'outil qui la contient.  Si l'on 
veut rendre une procédure visible dans l'ensemble des applicatifs il est indispensable de la stocker dans 
la base, ce qui la "généralise" et la rend potentiellement accessible à tous les utilisateurs connectés 
(dans la mesure où ils ont les privilèges adéquats).

Initialisation de variables hô tes dans les procédures:
Par exemple dans SqlPlus, après avoir déclaré une variable comme :
variable x number;
on peut dans un bloc Pl/SQL anonyme, lui affecter une valeur, par exemple :
:x := sqlcode;
Cela n'est possible que dans les procédures non stockées. Si l'on doit récupérer des valeurs rendant 
compte des conditions d'exécution d'une procédure ou d'un traitement quelconque, le meilleur outil est 
alors soit le passage de paramètres aux procédures, soit les valeurs de retour des fonctions.

R.Amore Page 26
Passages de paramètres dans les procédures
Soit le fragment de code suivant:
declare
  ....
  y number;
  procedure in_out (E integer , S OUT integer) IS // déclaration de la procédure
  begin
    s:=e;
  end;
begin
  in_out(52,y); // appel de la procédure
  :x := y; // x est une variable hôte (bind variable)
end;
/
print x; // x vaut maintenant 52
Il s'agit d'un bloc anonyme (dans SQL*Plus) commençant par le mot réservé declare. On y déclare la 
procédure in_out, avec un mot réservé OUT dans le descriptif des paramètres formels. Il existe trois 
mots réservés déterminant le sens dans lequel un paramètre pourra être utilisé dans et au dehors de la 
procédure:
IN  (par défaut. Par valeur lors de l'appel de la procédure)
OUT (l'appel comporte obligatoirement une variable à cette position)
IN OUT (l'équivalent d'un paramètre par adresse)

 F O N C T I O N S 
Soit:
Function Sal_ok (salaire real, titre real)
return boolean IS // Type retourné
min_sal  real; // Pas de mot clé Declare
max_sal real;
begin
select losal, hisal into min_sal, max_sal from sals
  where job = title;
Return (salaire >= min_sal) and (salaire <= max_sal);
end Sal_ok; // Sal_ok est optionnel
Cette fonction détermine si le salaire d'un employé est dans l'intervalle autorisé ou pas. Elle retourne une 
valeur booléenne calculée dans l'expression qui suit le Return (qui aurait pu être explicitement, True ou 
False ou Null). 
L'appel de cette fonction pourrait être :
If Sal_ok (Valeur1, Valeur2) then
  ...
end if;
ou bien
Nom_Variable := Sal_ok (Valeur1, Valeur2);
Une restriction: les fonctions peuvent apparaître dans les procédures mais pas dans les commandes 
SQL.
On peut obtenir des informations interessantes sur les procédures et fonctions par les tables :
ALL_ERRORS, USER_ERRORS, DBA_ERRORS
ALL_SOURCE, ...
USER_OBJECT_SIZE,...

R.Amore Page 27
 T R I G G E R S 
Exemple
Voici un trigger assez typique quant à sa syntaxe ...
CREATE OR REPLACE TRIGGER archiver
AFTER INSERT OR DELETE OR UPDATE ON test // test est une table d'essai
FOR EACH ROW // c'est un trigger sur ligne
DECLARE
  y number;
  msg char;
BEGIN
  IF INSERTING THEN
    insert into archiv
values('I', sysdate,1);
    RAISE_APPLICATION_ERROR (­20501,attention, ...insertion');
  ELSIF UPDATING THEN
    insert into archiv
values('U', sysdate,2);
    RAISE_APPLICATION_ERROR (­20502,'attention, ... mise a jour');
  ELSIF DELETING THEN
    insert into archiv
values('D', sysdate,3);
   RAISE_APPLICATION_ERROR (­20503,'attention, ... suppression');
  end if;
EXCEPTION when others then
  y := sqlcode;
  insert into archiv(oper,moment,code)
  values (msg,sysdate,y);
END;
/
ne fait que mettre en évidence quelques unes parmi les plus usitées des fonctionnalités des triggers.

Généralités ­ Définitions
Un trigger base de données est un ensemble de traitements PL/SQL
Il est déclenché implicitement et automatiquement par un ou plusieurs évènements prédéfinis.
Il est attaché à une et une seule table
Le déclenchement d'un trigger base de données peut entraîner le déclenchement d'autres triggers
Un trigger base de données est identifié par cinq caractéristiques:
♦ Un séquencement
⇒ Before
⇒ After
♦ Un type
⇒ par ordre
⇒ par ligne
♦ Un événement qui le déclenche
⇒ Insert
⇒ Update
⇒ Delete
♦ Des restrictions éventuelles
⇒ When

♦ Les ordres du traitement

R.Amore Page 28
Tr i g g e r s   e t   p r o c é d u r e s   s t o c k é e s
Un trigger base de données peut appeler une procédure stockée
Un trigger base de données est associé à une et une seule table
Un trigger base de données est appelé implicitement
Un trigger base de données sera opérationnel jusqu'à la suppression de la table sur laquelle il est défini 
ou s'il est inhibé explicitement
Les ordres Commit, Rollback, Savepoint sont interdits dans les triggers base de données.

Tr i g g e r s   p a r   o r d r e   e t   t r i g g e r s   l i g n e .
On utilisera un trigger par ordre si le traitement doit être effectué une seule fois pour l'ensemble des 
lignes.
Lors de l'utilisation d'un trigger ligne, le traitement défini dans le corps du trigger sera exécuté pour 
chaque ligne concernée de la table.
Dans l'utilisation des triggers ligne (et seulement dans ce cas!), on peut référencer l'ancienne et la 
nouvelle valeur d'une colonne par les variables old et new. Selon l'ordre SQL utilisé, ces deux variables 
prendront des valeurs différentes:
OLD NEW
Insert NULL Nouvelle valeur
Update Ancienne valeur Nouvelle valeur
Delete Ancienne valeur NULL
Ex: mise à jour conditionnelle pour toutes les lignes d'une table...
CREATE TRIGGER Maj_Comm
BEFORE Insert or Update OF Sal On Emp
For Each Row
When (new.job = 'SALESMAN') // On n'agit que sur certaines lignes de la table
BEGIN // Les variables old et new ne sont pas préfixées de ":"
       :new.comm := :old.comm * (:new.sal / :old.sal);
END;

Restrictions
Puisqu'il est possible de déclencher un trigger par plusieurs évènements, il est intéressant de pouvoir 
distinguer, dans le corps du trigger, quel est l'événement dont il s'agit. Par les clauses:
⇒ if inserting
⇒ if updating
⇒ if deleting
Contrairement aux procédures et aux fonctions
⇒ Le pseudo­code du trigger n'est pas stocké dans la base
⇒ Pas de commande SHOW ERRORS
⇒ à chaque appel, le trigger est automatiquement recompilé.
Un trigger peut être désactivé ou réactivé par :
ALTER TRIGGER Nom_Trigger DISABLE  (ou ENABLE)
ou
ALTER TABLE Nom_Table DISABLE ALL TRIGGERS
Pour visualiser les triggers existants, on peut interroger la vue de dictionnaire de données 
USER_TRIGGERS. Voir aussi ALL_TRIGGERS, DBA_TRIGGERS.

R.Amore Page 29