Vous êtes sur la page 1sur 114

OCP 

Oracle (PLSQL) :
Le Langage PL/SQL

Chaieb Chiheb ©
16/03/2021

16/03/2021 Pr. Chaieb Chiheb  © 1
Introduction Au PL/SQL 

• Définition : PL/SQL est un langage algorithmique


procédural considéré comme une extension du SQL,
intégré au serveur Oracle (Moteur PL/SQL) . Il permet
de développer des programmes et des modules stockés
dans la base appelés par des programmes
d’application (Java, Jdevelopper , Web, ..) ou pour
contrôler les transactions utilisateurs. C’est un langage
de programmation à la fois puissant, simple et
moderne destiné à :
 Résoudre de problèmes complexe (dépasse le SQL)
 Exprimer facilement les règles de gestion complexes (CI)
sous forme de procédures et de triggers stockés.

16/03/2021 Pr. Chaieb Chiheb  © 2
Caractéristiques du Langage 
 Intégration parfaite des ordres LMD du SQL : 
Insert, Update, Delete, Select ;
 Instructions procédurales : 
• Déclarations de variables, constantes, curseurs ....
• Instructions conditionnelles : if else, elsif …
• Instructions répétitives : while, for, loop …
 Traitement de curseurs utilisateurs.
 Avec PL/SQL on construit un programme complet 
(déclaration+traitement) dont l’exécution est 
transactionnelle.

16/03/2021 Pr. Chaieb Chiheb  © 3
Structure des modules PL/SQL

Une structure de « bloc »
 Le PL/SQL n’interprète pas une commande, mais 
un ensemble de commandes contenues dans un 
« bloc » PL/SQL. Ce bloc peut comporter 
plusieurs « sous‐blocs ». Sa structure est simple 
d’apprentissage et lisible en termes de 
maintenance de programmes.
 Ce bloc sera utilisé comme un programme simple, 
ou pour implémenter une fonction cataloguée ou 
un déclencheur de base de données.
 Ce bloc PL/SQL est constitué de trois sections

16/03/2021 Pr. Chaieb Chiheb  © 4
Sections PL/SQL
 La section Declare, réservée pour la déclaration 
de variables, des constantes, d'exceptions et des 
curseurs. Cette section peut être parfois absente 
en cas d'absence des déclarations. 
 La section Begin exécutable dont sa présence est 
obligatoire, comporte les instructions à exécuter 
du programme. Elle se compare à la structure d'un 
programme quelconque écrit avec un langage 
algorithmique.
 La section de gestion d'exceptions et qui est 
réservée pour le traitement des anomalies 
internes (générées par le noyau) et externes 
définies par le programmeur.
16/03/2021 Pr. Chaieb Chiheb  © 5
Sections d’un Bloc PL/SQL 2
• La section obligatoire d’un bloc est la section
exécutable délimitée par le BEGIN et le END. Elle
peut être précédée d’une section optionnelle de
déclaration de variables, DECLARE, puis d’une
zone optionnelle de traitement des erreurs,
EXCEPTION.
DECLARE
‐‐ zone de déclaration de variables
BEGIN
‐‐ traitements ...
EXCEPTION
‐‐ traitement des erreurs rencontrées
END;

16/03/2021 Pr. Chaieb Chiheb  © 6
Section Declare

• Cette section est optionnelle, toute fois les variables et


les constantes utilisées dans le programme, doivent
impérativement être déclarées dans cette section ce
qui rend son existence est obligatoire. Elle commence
par le mot Declare et se termine avant le début de
l'autre section exécutable commençant par le mot
Begin. Une instruction de déclaration fait l'objet d'une
seule variable ou d'une seule constante. La déclaration
consiste à attribuer à la variable ou à la constante un
nom, un type et une valeur optionnelle. Chaque
déclaration s'écrit sur une ligne se terminant par un
point virgule.

16/03/2021 Pr. Chaieb Chiheb  © 7
Section Exécutable 

C'est la section obligatoire d'un programme PL/SQL,


Elle commence par le mot clé Begin et s'étend
jusqu'au début de la section d'exceptions. Elle
comporte toutes les instructions exécutables du
programme. Chaque instruction doit se terminer
par un point virgule. Ses instructions sont
essentiellement des catégories suivantes :
instruction d'affectation
instructions conditionnelles
instructions répétitives
instructions SQL du L.M.D
instructions de traitement des curseurs

16/03/2021 Pr. Chaieb Chiheb  © 8
Les variables PL/SQL
• PL/SQL permet de déclarer des variables et des
constantes, puis de les utiliser dans la section de
traitements. Cette déclaration est impérative avant
leurs utilisation, elle s’effectue dans la zone DECLARE.
• Les types de variables :
– Les nombres : number(n,m) , float, integer, ..
– Les chaînes : char(n), varchar2(n) ;
– Les date heures : date;
– Les booléens : boolean (true, false, null).
– Objets : clob, blob

16/03/2021 Pr. Chaieb Chiheb  © 9
Remarques 

 Une déclaration par ligne


 Chaque déclaration se termine par un ;
 Les commentaires sont ‐‐ sur une ligne /* un
commentaire long sur n lignes */
 Le nom de variable (identificateur) est
constitué de :
Lettres alphabétiques , chiffres et _
N’utiliser pas les mots réservés du langage.

16/03/2021 Pr. Chaieb Chiheb  © 10
Les variables Numériques
 Une variable numérique peut être déclarée dans l’un de types 
suivants selon le besoin : 
 Float, real : une réel flottant : 1.222222,  5E3
 Integer : entier relatif  : 12, 2333, ‐87 
 Number (n) : entier relatif de n chiffres au 
maximum : 1.. 9999
Declare
 Number (n,m) : nombre décimal de n chiffres 
N  float ;
total , avec une précision de m décimaux : 12.89, ‐
Prix number(8,3);
234.01  n=6 , m=2 Compteur number(4); 
………………

16/03/2021 Pr. Chaieb Chiheb  © 11
Les variables chaînes 
 Char(n) : une variable de ce type stocke une
chaine de n caractères. N<= 32767. espace
réservé à l’avance et lui même alloué.
 Varchar2(n) : une variable de taille variable.
L’espace est alloué selon la valeur affectée.
• Long : pour stocker de quantité de texte
importante pouvant atteindre deux milliard de
caractères . DECLARE
Ville char(15) ;
Adresse  VARCHAR2(30);
Sexe char ; 
BEGIN
16/03/2021 Ville  := ‘Sidi BouZid’;
Pr. Chaieb Chiheb  © 12
Adresse := ‘12 Rue la Révolution ‘ ;
Variables de type Date – Heure 

• Représentant le type date heure selon plusieurs 
formats. 
• Le paramètre de configuration oracle NLS_Date_format
(dans le base des registres d'oracle) permet de 
spécifier le format de la date et qui peut prendre l'une 
des formes suivantes : 
• dd/mm/yy , dd/mm/yyyy , dd‐mm‐yy, dd‐month‐yyyy : 
18/02/11 ou 18‐Février –
Declare 2011, 
• Une variable date peut comporter l’heure aussi selon le 
d  date ;
format hh24:mi:ssheure date ;  
, hh12:mi:ss
‐‐ mémoriser la date et l’heure jour 
• Une constante date est entourée par deux 
Begin 
apostrophes.  d := ‘13‐02‐15’; 
heure := to_date (sydate, ‘dd‐mm‐yy hh24:mi');

16/03/2021 Pr. Chaieb Chiheb  © 13
Le Type Logique 

• Boolean : est un type composé des valeurs 
booléennes « True, False, Null ». Seules les 
variables peuvent avoir ce type, et non les 
colonnes de tables. Une variable logique 
intervient dans l'évaluation d'une condition (si b 
est une variable logique, on peut écrire b:= x<y). 
• Les opérateurs principaux sont : ! (not) , and, Or. 
• b1:=( x<y) or( z!=w);  b1 Boolean;  b2 Boolean;
• b2 := not (b1); 
16/03/2021 Pr. Chaieb Chiheb  © 14
Le type record (structure) 

• Une structure regroupe plusieurs champs de types


variés et qui désigne un objet. Un employé est
caractérisé par un code, un nom, un grade etc.. Tous
ces éléments seront regroupés dans une entité
structure qu’on peut la définir :
• Type employe is record 
( code number, nom varcha2(25), date_nais date, grade 
char(15) ) ; 
E1 employe;  ‐‐ déclarer une variable E1 de type employe
E1.code := 12; 
E1.nom :=  ‘Ahmed Mouradi’; ….

16/03/2021 Pr. Chaieb Chiheb  © 15
Déclaration de variables et constantes
• La déclaration d'une variable consiste à allouer un espace
dans la mémoire pour stocker et modifier une valeur. Elle
est typée et peut recevoir une valeur lors de sa déclaration.
• Une constante est définie comme une variable dont le
contenu n’est peut pas être modifié dans le programme.
• La syntaxe de déclaration d'une variable (ou une constante)
prend plusieurs formes :
 Nom_variable[constant] data_type [not null] ;
 Nom_variable identifiant%type [not null] ;
 Nom_variable identifiant%rowtype avec : 
Identifiant : soit une colonne d’une table : table.colonne, soit
une table, soit le nom d’une autre variable.

16/03/2021 Pr. Chaieb Chiheb  © 16
Modèles de Déclarations 

• Une variable est déclarée de même type que :
la colonne d’une table : v1 client.nom%type;
Une autre variable : v2 v1%type;
Une table (variable structurée) : CL  client%rowtype;
Une variable peut être définie par référence au type 
d'une colonne d'une table 
• Initialiser une variable lors de sa déclaration : 
Nom_variable type := valeur| expression PL/SQL ; 
x real not null := 12 .3*25 ; 

16/03/2021 Pr. Chaieb Chiheb  © 17
Modèles de Déclarations 

• Declare
Totalc number(8,3); 
Nomc varchar2(15) : = 'Ahmed'; 
taille_nom number  := length(Nomc)*2 ; 
Datec date; 
Num_clt client.idclt%type; 
Name client.nom%type; 
Vclt client%rowtype; 
Pi constant number :=3.14; 

16/03/2021 Pr. Chaieb Chiheb  © 18
Initialisation de variables 

• Lors de sa déclaration dans la section Declare
• Au cours de son utilisation  section Exécution
Formes d’initialisation 
Variable := valeur |expression ;
– Expression compatible avec le type de la variable
– Expression numérique , chaîne logique ou date;
Select expression into variable from table where
condition; 
le select doit ramener une seule valeur à affecter dans la 
variable indiquée :

16/03/2021 Pr. Chaieb Chiheb  © 19
Initialisation de variables 

• Lors de sa déclaration dans la section Declare
• Au cours de son utilisation  section Exécution
Formes d’initialisation 
Variable := valeur |expression ;
– Expression compatible avec le type de la variable
– Expression numérique , chaîne logique ou date;
Select expression into variable from table where
condition; 
le select doit ramener une seule valeur à affecter dans la 
variable indiquée :

16/03/2021 Pr. Chaieb Chiheb  © 20
Initialisation de variables 

• Declare
vnum number(4) ;
vdate Commande.datec%type;
vmnt commande.mntc %type ;
Begin  
vnum :=10;
Select mntc into vmnt from commande where
numc= vnum;
Select datec into vdate from commande;
Select nom from client where idclt=1020;
End;
/

16/03/2021 Pr. Chaieb Chiheb  © 21
A Retenir 

• Le deuxième Select ramène plusieurs valeurs pour une 
variable : Faux l’erreur générée est too_many_values
• Le troisième select ramène une valeur dans aucune 
variable : une valeur est toujours contenu dans une 
variable en PL/SQL 
• A une variable on n’affecte qu’une seule valeur lui est 
compatible en type. 
• Select col1, col2, …Coli into V1, V2, …Vi  from …. Where
…..;  
• Cette requête doit impérativement  ramener qu’une 
seule valeur pour chacune des variables et qui est lui 
compatible.

16/03/2021 Pr. Chaieb Chiheb  © 22
Les Entrées Sortie avec PL/SQL 

Le langage PL/SQL ne dispose pas des fonctions d’E/S propres.


Par ailleurs pour afficher un message simple sur l’écran de l’user
qui exécute le programme PL/SQL ou pour saisir des données au
clavier nous faisons recours aux méthodes suivantes :
 La Commande Prompt
La commande d’interface SQL/PLUS « Prompt » permettant
l’affichage d’un message texte simple sous SQL/PLUS, elle
n’appartenant pas à la syntaxe PL/SQL. Elle ne peut être utilisée
qu’à l’extérieur du block (programme) PL/SQL. Nous pouvons
l’utiliser avant l’exécution du programme pour afficher certain
message avertissant l’utilisateur. Cette instruction peut figurée
avec le programme PL/SQL dans le même fichier script.

16/03/2021 Pr. Chaieb Chiheb  © 23
La commande Accept

Cette commande SQL/PLUS externe à la syntaxe de PL/SQL


permet de saisir une donnée sous SQL/PLUS. Cette donnée
saisie au clavier, sera mémorisée dans une variable externe
nommée. Tout ceci se fait à l’extérieur du programme
PL/SQL : pour accéder à cette variable à l’intérieur d’un
programmer PL/SQL, nous la referons par «&nomvariable».
Le symbole & utilisé avant la variable, mentionne qu’elle est
externe au block PL/SQL.
 Écrire un programme PL/SQL permettant de calculer le
volume d’un cylindre. Entrées R,H.
 Écrire un programme permettant de calculer le chiffre
d’affaire d’un client (total commandes net) et le nombre de ses
commandes. Le numéro client est donné.

16/03/2021 Pr. Chaieb Chiheb  © 24
Solution
prompt donner le code Client
accept code

declare

n integer ; ‐‐ n est le nombre de commandes


ca float ; ‐‐ ca est le chiffre d'affaire à calculer

begin

select sum(mntc ‐ mntc*remise ) , count (numc) into ca, n from commande


where idclt=&code;

dbms_output.put_line (' Chiffre Affaire = '||ca || 'Nombre de Commande = '||n);


end;
/

16/03/2021 Pr. Chaieb Chiheb  © 25
Utilisation du package « Dbms_output » 

Nous pouvons faire recours au package PL/SQL « dbms_output » pour


afficher sur l’écran un message simple, la valeur d’une variable ou une
expression PL/SQL. Ceci en faisant recours à la fonction put_line() :
dbms_output.put_line(‘message’) » Put_line est la fonction du package
permettant l’écriture à l’écran. Pour afficher un message et/ou une
expression:
• bms_output.Put_line(‘message’||expression);
l’expression peut être une variable. Exemple :
Declare
Activer le serveur output :
vqs article.qtestk%type; Set serveroutput on 
vpv article.pu%type;  Désactiver les remplacements : 
vtx article.tva%type; set verify off
begin
Select Qtestk,pu,tva into vqs,vpv,vtx from Article where idart=&vcode; 
dbms_output.put_line (‘Prix de Vente : ‘|| vpv*(1+vtx)|| ‘Stock : ’||vqs) ; 
End;/

16/03/2021 Pr. Chaieb Chiheb  © 26
Structures de Contrôle
1. La structure If then else 
Les instructions conditionnelles permettent de contrôler le
moment où une séquence des commandes est exécutée si
une condition est vraie, sinon c'est éventuellement une autre
séquence de traitement qui sera exécutée. La syntaxe est :
If condition then
Traitement A ; 
else
Traitement B; 
end if ; 
• Remarquer la présence de l’espace entre le ‘end’ et le ‘if’. 
• La condition est une expression logique pouvant utiliser des 
variables et des constantes ainsi que tous les opérateurs du 
SQL:    =, >, <, <=, >=, <>, IS [NOT] NULL, And, OR, In. 

16/03/2021 Pr. Chaieb Chiheb  © 27
Structures de Contrôle
2. La structure multi choix :  If then elsif , elsif

If condition then
Traitement I
elsif condition2 then
traitement II
elsif condition 3 then
…………
[else
…  ]
end if;

16/03/2021 Pr. Chaieb Chiheb  © 28
Exercice : Traitement Conditionnel
• Écrire un programme PL/SQL qui calcule le nouveau prix unitaire d’un
article donné, en augmentant de +20% son ancien prix unitaire si la
quantité totale vendue de l’article est >= 20, sinon diminuer son PU de
8%. Ce programme met à jour le PU de l’article concerné et affiche à
l’écran les données suivantes : desart , Ancien PU, Nouveau PU, Stock .
Tester votre programmes avec les article 1, 3 et 5.
• Déterminer le chiffre d’affaire net (noté CaClientNet) d’un lient donné
calculé à la base des commandes lancées par le client selon les règles
suivantes :
Si le type de Client=‘P’ alors CAClientNet =∑(Montant Commande Net)
Si le type de Client= ‘O’ alors CAClientNet =∑(Montant Commande Net) + 2%
Si le type de Client= ‘R’ alors CAClientNet =∑(Montant Commande Net) + 6%

le programme affichera le nom client, son type (Passager/ Occasionnel/


Résident) et son Chiffre d’affaire.

16/03/2021 Pr. Chaieb Chiheb  © 29
Exercice 1 : Solution
accept vcode
declare
apu article.pu%type;         ‐‐ ancien PU
npu article.pu%type;       ‐‐ Nouveau PU
Qtot lig_com.Qtecom%type  ;   ‐‐ total des quantités commandés de l'article
des article.desart%type;
begin
select sum (qte_com) into Qtot from lig_com where idart=&vcode;
select pu, desart into apu , des  from article where idart= &vcode;
if Qtot >= 20 then
npu := apu*1.2; Activer le serveur output :
else Set serveroutput on 
npu := apu*0.92;
Désactiver les remplacements : 
set verify off
end if;
dbms_output.put_line ('Article : '|| des|| 'Acien PU :'|| apu|| 'Nouv PU : '||npu );
update article  Set pu = npu where idart=&vcode;
end;
/

16/03/2021 Pr. Chaieb Chiheb  © 30
Les Structures Répétitives
• Les boucles permettent de répéter une suite d'instructions plusieurs fois. Ce nombre de fois peut être indiqué à l'avance, ou non. Dans ce dernier cas 
l'arrêt de la boucle est contrôlé par la validité d'une condition. PL/SQL offre les boucles : Loop, For et While. 
La structure Loop 
Loop
…   .exit when condition 
end loop;
Calculer la somme arithmétique et la moyenne d’un entier N saisi. S=1+2+3+.. +N. 
Prompt Donner votre nombre 
Accept n       
Declare
I integer ;                           
S integer; 
M float; 
Begin 
S:=0;  
i:= 1;
Loop
s: = s+i;
i := i +1 
exit when i> &n;
End loop ;
M:= s/n;
dbms_output.put_line ( ‘Somme : ‘|| s ||  ‘ Moyenne : ‘|| M );
End;/
16/03/2021 Pr. Chaieb Chiheb  © 31
Les Structures Répétitives

La boucle while  
Cd
While (condition ) Non

Loop
…….Traitement 
Traitement  T
End loop; 

16/03/2021 Pr. Chaieb Chiheb  © 32
La structure while

• Le traitement contenu dans la boucle sera


exécuté en tant de fois que la condition
mentionnée est encore valide. Cela veut dire
que la condition va être affectée par le
traitement à exécuter pour qu’elle devienne
invalide au bout d’un nombre des exécutions
sinon on aura une boucle infinie.

16/03/2021 Pr. Chaieb Chiheb  © 33
Les Structures Répétitives

Exemple :    Calculer le factoriel de n , nombre saisi.
Accept n 
Declare
P integer :=1;
i  integer ;
Begin
i:=1;
While (i<=&n )
loop
p:= p*i;
i:=i+1;
End loop;
Dbms_output.put_line (‘Le factoriel   est : ‘||p);
End;/

16/03/2021 Pr. Chaieb Chiheb  © 34
Les Structures Répétitives
La boucle For
• Cette structure exécute un traitement répétitif pour un
nombre de fois donné de 1 à n. A cet effet nous utilisons un
compteur initialisé avec une valeur initiale (1) et qui
s'incrémente à chaque itération automatiquement jusqu'à
l'atteinte de la valeur max (n).
For  i in 1.. N 
loop
….. Traitement 
End loop;
Exercice 
Écrire un programme qui détermine tous les diviseurs propres 
d'un nombre saisi au clavier. 

16/03/2021 Pr. Chaieb Chiheb  © 35
Les Curseurs PL/SQL

16/03/2021 Pr. Chaieb Chiheb  © 36
Les Curseurs en PL/SQL 
 Pour traiter une commande SQL (select .., update .. etc.
), le programme PL/SQL ouvre une zone de contexte
pour exécuter la requête et y stocker les données
instantanément avant de les afficher et les transférer
vers/de la BD.
 Le curseur permet de nommer cette zone de contexte,
d'accéder aux informations individuellement (en cas
des plusieurs lignes retournées par la commande SQL)
et éventuellement contrôler leur traitement.
 On distingue deux type de curseurs : les curseurs
implicites crées et gérés par le système et ceux
explicites créés et gérés par le programmeur dans des
situations appropriées.

16/03/2021 Pr. Chaieb Chiheb  © 37
Les Curseurs explicites 
 Ce type de curseur est créé et est géré par l'utilisateur
pour traiter un ordre Select qui ramène plusieurs lignes.
Le curseur va permettre le stockage et le traitement de
tous les tuples ramenés par le Select dont l'objectif de
les traiter ligne par ligne.
 De ce fait un Select ramenant plusieurs lignes de
données et qui est traité par un curseur ne va pas
générer l'erreur "Too_many_rows". Dans ce qui suit
nous s'intéressons aux curseurs explicites : leur
déclaration et leur manipulation.
 Pour utiliser un curseur on doit passer par quatre
étapes : la déclaration, l'ouverture, le traitement des
données et en fin la fermeture du curseur.

16/03/2021 Pr. Chaieb Chiheb  © 38
Déclaration d'un Curseur 
 La déclaration d'un curseur se fait toujours dans la section
Déclare dans un programme PL/SQL avec les variables et les
types.
 La déclaration d'un curseur se base sur la définition d'un ordre
Select qui détermine les lignes qui vont être ramenées de la
base et stockées dans la zone mémoire réservée au curseur.
La syntaxe de déclaration d'un curseur est :
Cursor nom_curseur [(par1 type, par2 type, ..)] 
Is requête _Select ; 
• Requête_Select : est tout ordre select valable. 
Exemple: 
Declare
Cursor client_R is Select  * from client  where typec=‘R’;
Vclient client_R%rowtype;  ‐‐ déclaration d’une variable structurée

16/03/2021 Pr. Chaieb Chiheb  © 39
Utilisation de curseur
 Dans la section exécutable que l’ouverture , le traitement et la
fermeture du curseur vont se faire.
 Avant le traitement du curseur, il faut toujours l'ouvrir, et la fin du
traitement il sera fermé.
L'ouverture du curseur se fait par l’instruction:
Open nom_curseur;
Pour fermer le curseur on écrit :
Close nom_curseur;
Exemple :
Begin
Open client_R; // remplissage du curseur
……T……
Close client_R; // destruction du curseur et libération espace

16/03/2021 Pr. Chaieb Chiheb  © 40
Traitement du curseur

 Les lignes ramenées par le curseur seront traitées une par une
jusqu'à la dernière ligne. Pour pouvoir traiter un curseur ligne
par ligne, il faut récupérer chaque fois une ligne ramenée
depuis le curseur avant de traiter la suivante. Une ligne lue
depuis le curseur sera affectée dans des variables réceptrices
compatibles et qui sont déclarées avant, ou dans une variable
structure déclarée de même type que le curseur (%rowtype).
 La lecture d’une ligne curseur : fetch nom_curseur into var1,
var2, ..varn | var_structurée;
 Pour traiter toutes les lignes du curseur on utilise une
structure de boucle dont la condition d’arrêt est la fin de
curseur.

16/03/2021 Pr. Chaieb Chiheb  © 41
Traitement du curseur
Declare
Cursor client_R is Select idclt, nom, ville,typec from client ;
categ char(10);
vclient client_R%rowtype;   ‐‐ variable de lecture
Begin 
open client_R; 
Loop 
Fetch client_R into vclient ; 
Exit when client_R%notfound;
if (vclient.typec='R') then categ :='Résident';
elsif (vclient.typec='P') then categ :='Passager';
Elsif (vclient.typec='O') then categ :='Ocasionnel';
End if;
dbms_output.put_line('Client : '||vclient.nom || '   '||vclient.ville || '  '|| categ);
end loop; 
close client_R;
End; /

16/03/2021 Pr. Chaieb Chiheb  © 42
Attributs du curseur
• Les attributs d'un curseur permettent de tester le résultat de
l'exécution d'un curseur, ils ont une valeur booléenne ou autre. Ces
attributs sont les suivants :
 Nom_curseur%found nom_curseur%notfound
Cet attribut est vrai si le Fetch ramène une ligne, sinon alors l'attribut
nom_curseur%notfound est vrai.
 Nom_curseur%rowcount
Cet attribut est de type numérique. Il exprime le nombre des lignes courant
ramenées par le 'fetch'. L'attribut rowcount du curseur est :
– incrémenté à chaque ordre 'fetch'
– il traduit donc le nième ligne traitée.
Exemple :
Afficher les n commandes les plus chères pour l’année en cours. N est saisi.
 Nom_curseur%rowtype : pour déclarer une variable de même
structure.

16/03/2021 Pr. Chaieb Chiheb  © 43
Application

• Développer un programme PL/SQL qui calcule et affiche pour


chaque client son chiffre d’affaire net selon la formule
suivante :
• CA_Net = Ca_Brut *taux. Avec Ca_brut = la somme de
montant commandes client net (moins la remise).
• Taux = 1.1 si le client est de type R et qui a réalisé plus de 10
commandes sinon taux = 1.05.
• Taux = 1.02 pour les clients d’autres types (P,O) qui ont
réalisés plus de 5 commandes , sinon Taux=1.
Le résultat est récupéré dans la table suivante : 
T_Sortie (Idclt, Nom, Ville, TypeC, Nombre_Com, Ca_net) 

16/03/2021 Pr. Chaieb Chiheb  © 44
la boucle for et les curseurs
 L'objectif est de fournir au programmeur une structure
simple et efficace pour utiliser les structures de boucle et
les curseurs. En effet il s’agit d’écrire le même code
PL/SQL mais sous une autre forme qui est plus optimisée
en remplaçant la structure de boucle classique « Loop ..
End loop » par la boucle « For …. End loop ; ».
 La structure for, permettra d’écrire le même code PL/SQL,
mais sous une forme optimisé, où certaines instructions
de traitement de curseur vont être éliminées et qui vont
devenir implicites.
 Le traitement d’un curseur passe toujours par des étapes
répétitives : déclaration d’une variable de lecture,
ouverture du curseur , le fetch , et la fermeture : rendre
ces étapes implicites avec la boucle for.

16/03/2021 Pr. Chaieb Chiheb  © 45
la boucle for et les curseurs
• Schéma classique : 
Schéma optimisé 
Declare
Cursor cR is select ….
Declare
V cR%rowtype; Cursor cR is Select …..
Begin Begin
Open cR; For vrec in cR
Loop Loop
Fetch cR into V; ….T
Exit when cR%notfound; End loop;
…. T  End;
End loop;
Close cR;
End;

16/03/2021 Pr. Chaieb Chiheb  © 46
Application 1 

Exemple 
1. Ecrire un programme PL/SQL permettant de calculer le
nouveau prix unitaire des articles (vendus dans l'année
en cours) selon la formule suivante : « Npu = pu * taux»
avec taux = +7% si le montant de vente de l'article durant
l'année en cours est plus de 5000 Dinars sinon taux = ‐
10%.
Le résultat est récupéré dans la table suivante :
T_Resultat : (Idart, Desart, PU, NPU, Taux) , taux = +7%, ‐
10%.
2. On se propose de calculer la quantité
d'approvisionnement QteApp des articles stockés.

16/03/2021 Pr. Chaieb Chiheb  © 47
Application 2
Programme de Facturation : créer les factures clients. 
 Créer la table Facture (Idfac, dateFac, mntFac, numc#). 
 Une facture correspond à une commande client non facturée 
avant. 
 Le champ idfac est de type chaine constitué de numc, concaténé 
avec le idclt ,le jour et le mois de la commande. Exemple : 10‐
1000‐25‐11 : numc=10, idclt=1000, jj:25 mm:11. 
 mntFac=(mntc‐ remise) +Tva ‐ RemiseFac
Tva = 12%  si le client est de Type ‘R’
Tva = 15% pour les autres types clients. 
RemiseFac = 10% si mntFacHt >5000, sinon 5%.

 Ce programme utilisera un curseur qui ramène toutes les


commandes clients de la base. pour chaque commande élaborer sa
facture et l’enregistrer dans la table Facture. Une commande
facturée passe à l’état 1 (ajouter le champ etatCom de type short à
la table commande) .

16/03/2021 Pr. Chaieb Chiheb  © 48
Les Curseurs paramétrés 

• Un curseur paramétré utilise des variables dans sa définition. Les


variables prennent des valeurs lors de l’exécution du curseur. Par
conséquent les lignes ramenées par un curseur paramétré peuvent
variées d’une exécution à une autre, elles dépendent des valeurs
des paramètres spécifiées lors de l’exécution du curseur. Un curseur
paramétré est déclaré avec la syntaxe suivante :
Cursor nom_curseur (param1 type, param2 type, .. ) 
Is select ordre_select; 
• L’ordre Select utilise les paramètres qui peuvent être de type : char, 
number, date et boolean sans spécifier leur longueur. 
Begin 
Open nom_curseur(valeur1, valeur2, ..);
• A l’ouverture du curseur , les valeurs correspondant aux paramètres 
seront assignées.

16/03/2021 Pr. Chaieb Chiheb  © 49
Les Curseurs paramétrés 

Exemple

Declare 
Cursor c1 (town char) is select idclt, nom, ca from client where ville = town;
Tot_ca number :=0;
Nb_ca_sup number := 0;
Begin
For c1_rec in c1('Sousse') loop
Tot_ca := tot_ca + c1_rec.ca;
If c1_rec.ca > 2000 then 
Nb_ca_sup : = Nb_ca_sup + 1;
End if;
End loop;
Insert into temp values ('Sousse', tot_ca, Nb_ca_sup);
End;
/

16/03/2021 Pr. Chaieb Chiheb  © 50
Application1‐ Les Curseurs paramétrés 

Nous souhaitons réaliser la facturation des commandes clients. Une commande est à l’état 0 si
elle n’est pas facturée, sinon elle passe à l’état 1. elle comporte aussi un champ idFac
désignant la facture correspondante .
Travail demandé : Développer un programme PL/SQL qui réalise la facturation des clients avec
les indications suivantes :
• Utiliser un curseur qui ramène tous les clients (idlt, typeC ) ayant des commandes non
facturées.
• Un deuxième curseur paramétré (idclt ) ramenant les commandes d’un client .
• Une facture client regroupe toutes les commandes non facturées d’un client : (numf, datef,
mntFac, idclt)
• numéro facture(numf) est un numéro sous la forme idclt‐YY‐N où idclt est le code client , YY
est l’année en cours (deux chiffres) et N et un nombre récupéré depuis la séquence seqIdFac
• montant facture (mntFac) = mntFacBrut ‐ RemiseFac, Avec :
• mntFacBrut = ∑(MntNetCom+Tva) , Tva=+10%MntNetCom pour les commandes
comportant plus que 5 article sinon tva= +18%. MntNetCom = Mntc‐ Remise*Mntc.
• RemiseFac = 12% si le client est de type R, sinon RemiseFac=5% (type O) sinon 0%.
• Insérer la facture dans la table facture avec dateFac est la date du jour. Et mettre à jour les
commandes associées (état devient 1, renseigner le cham idFac ).

16/03/2021 Pr. Chaieb Chiheb  © 51
Application2‐ Les Curseurs paramétrés 

• Nous souhaitons réaliser la livraison des commandes clients, pour ce faire nous vous demandons de 
développer un programme PL/SQL qui réalise cette tache suivant les indications suivantes : 
• Chaque livraison correspond à un seul client et regroupe toutes ses commandes facturées et non 
livrées. 
• Créer la table Livraison (idLiv, dateLiv, adrLiv, nbrCom idclt#).
• Ajouter le champ idLiv dans la table commande comme clé étrangère 
• Définir un curseur qui ramène tous les clients ayant des commandes facturées et non livrées.  
Cursor Clt (idClt, Adresse) 
• Définir un deuxième curseur paramétré sur le code client ramenant les articles (idArt, totQteCom) 
sujets des ces commandes  regroupés par article. totSteCom et la somme des quantités 
commandées regroupées par article. 
• Elaborer pour chaque client, sa livraison. La dateLiv est la date du jour et l'adrLiv est l'adresse du 
client correspondant (ou la ville si l'adresse est indisponible). 
• Le numéro livraison(numl) est un numéro sous la forme  Idclt‐mm‐N où mm est le numéro de mois 
courant(1,2, ..12), et N et un nombre généré par une séquence à créer (seqNuml). 
• Créer la table DetailLiv (numL, idart, QteLiv) et la renseigner avec les données correspondantes, la 
QteLiv est la somme de qteCom d’un même article (dans différentes commandes) 
• Mette à jour le stock des articles livrés ( table Article)
• Le programme affichera un compte rendu des livraisons :
Numl,  dateLiv, nomClient, adrLiv, nbrCom livrés 

16/03/2021 Pr. Chaieb Chiheb  © 52
Application2‐ Solution 

declare
Cursor clt is select distinct c. idclt, ville  from commande  c , client l where c.idclt=l.idclt and idLiv is Null;   ‐‐ clients 
ayant de commandes
Cursor ArtCom (idc number) is select idart,sum(qtecom) as totQte from commande c, lig_com l  
where c.numc= l.numc and idclt= idc and idLiv is Null group by idart ;
numl livraison.idLiv%type; n  number(2);
begin
for vclt in clt
loop
n:=0;
select count(numc) into n from commande where idclt=vclt.idclt;  ‐‐ nombre de commandes
numl := vclt.idclt||'‐'||to_char(sysdate,'dd‐mm')|| '‐'|| to_char(sidLiv.nextVal);
for vArtCom in ArtCom(vclt.idclt)    ‐‐ pour chaque Article commandé 
loop
insert into detailLiv values (numl, vArtCom.idart, vArtCom.totQte);
end loop;
insert into livraison values (numl,sysdate,vclt.ville,n,vclt.idclt);
update commande set idliv=numl where idclt = v.idclt and idliv is null ;
end loop;
end;

16/03/2021 Pr. Chaieb Chiheb  © 53
Les exceptions (erreurs)

• Un programme PL/SQL en exécution peut générer des


erreurs telles que l'accès à une donnée non existante
dans la base, l'affectation de plusieurs données à une
seule variable, une division par zéro ou l’affectation
d’une valeur incompatible à une variable, la violation
d’une contrainte d’unicité etc.
• En présence de telles erreurs (non prévues), l’exécution 
du programme ne sera pas achevée correctement et ce 
dernier sera rejeté par le noyau Oracle en affichant sur 
l’écran de l’utilisateur des messages d’erreurs. 

16/03/2021 Pr. Chaieb Chiheb  © 54
Exceptions internes et externes

• Ces erreurs sont appelées par PL/SQL des


exceptions et sont gérées par le gestionnaire
des exceptions permettant au développeur de
planifier leurs gestions et d'abandonner ou de
continuer le traitement en leur présence. Cela
évitera le rejet du programme en cours
d’exécution. Ce mécanisme de gestion des
erreurs permettra de définir le traitement
approprié que le système doit exécuter en
présence d'une erreur.
16/03/2021 Pr. Chaieb Chiheb  © 55
Exception internes

 Une erreur interne est produite quand un bloc PLSQL


viole une règle d'Oracle ou dépasse une limite
dépendant du système d'exploitation. Dans ce cas la
main est rendue directement au système environnant.
 Ces erreurs internes générées par le noyau oracle sont
numérotées, or le gestionnaire des exceptions de
PL/SQL ne sait gérer que des exceptions nommées.
Pour cela, PL/SQL a redéfini quelques erreurs Oracle
comme des exceptions. Ainsi, pour gérer d'autres
erreurs Oracle, l'utilisateur doit utiliser le gestionnaire
OTHERS ou EXCEPTION_INIT pour nommer ces erreurs.
Le tableau suivant énumère les erreurs internes gérées
par le gestionnaire des exceptions :
16/03/2021 Pr. Chaieb Chiheb  © 56
Exception internes

• Nom d'exception  Erreur oracle 
• No_data_found ORA‐01403 
• Too_many_rows ORA‐01422 
• Value_error ORA‐06502 
• Zero_devide ORA‐01476 
• Invalid_number ORA‐01722 
• Value_Error ORA‐01001 
• Dup_val_on_index ORA‐00001 
• Invalid_Cursor ORA‐01001 
• Program_error ORA‐06501 
• Not_logged_on ORA‐01012 
• Transaction_backed_out ORA‐06001 

16/03/2021 Pr. Chaieb Chiheb  © 57
Exception internes

• La gestion d'exception consiste à définir dans 
le bloc 'Exception' le traitement à envisager 
lors de réalisation de l'exception; ceci consiste 
à utiliser la clause : 
• When nom_d'exception then : 
• Traitement en cas d'exception

16/03/2021 Pr. Chaieb Chiheb  © 58
Les Erreurs externes 

• PL/SQL permet à l'utilisateur de définir ses propres exceptions. La gestion des 
anomalies utilisateur peut se faire dans un programme PL/SQL en effectuant les 
opérations suivantes : 
• Nommer l'anomalie (de type exception) dans la partie Declare du bloc. 
Declare
‐‐ déclaration de l'exception 
Nom_ano exception; 
Begin 
…. 
‐ Déterminer l'erreur (condition d'apparition) et passer la main au traitement 
approprié par la commande Raise. 
If (condition_anomalie ) then raise nom_anomalie; 
Exception 
‐ Effectuer le traitement défini dans la partie exception du bloc. 
When (nom_ano) then (traitement ); 
….. 
End; 

16/03/2021 Pr. Chaieb Chiheb  © 59
Application

Exemple 
Développer un programme PL/SQL qui calcule le chiffre
d'affaire net d'un client (ca_net) dont le code est saisi. Ce
programme affiche un message d'erreur si le code client est
introuvable. Ce programme prévoit le cas où le nombre de
commande est 0 via une exception externe. Voici un
pseudo algorithme de ce programme.
Ca_net = ca_brut*taux; 
Si nombre de commandes >100 alors 
Taux = 1.1 *cn/nc
Sinon taux = 1.05*cn/nc
Avec cn est le nombre des commandes du client, nc est le 
nombre total des commandes. 
16/03/2021 Pr. Chaieb Chiheb  © 60
Les Fonctions et les Procédures 

16/03/2021 Pr. Chaieb Chiheb  © 61
Les Fonctions et Les Procédures Stockées
 Une procédure est une unité de traitement en PL/SQL dont la
structure ressemble à un bloc PL/SQL ordinaire mais qui est
nommée. Elle comporte les mêmes instructions qu’un
module PL/SQL (requêtes SQL (LMD), des instructions
PL/SQL, des variables, des constantes, des curseurs et un
gestionnaire d'exception ).
 Une fonction est une procédure qui calcule et retourne une
seule valeur : c’est une procédure particulière.
 Les fonctions et les procédures sont créées comme des objets
de la base. Une fois créées, elles seront stockées dans la base
parmi les autres objets contenus dans le schéma de son
créateur.
 Une procédure ou une fonction peut être appelée depuis
l’interface SQL/Plus , depuis un programme PL/SQL ou
n’importe quel autre module Oracle Forms, Oracle Reports,
Java etc.
16/03/2021 Pr. Chaieb Chiheb  © 62
Création des procédures et fonctions
 Une procédure/fonction est créée par la requête suivante : 
Create procedure <nom_procedure> [(liste d'arguments)]   {Is|As }  bloc 
PL/SQL ;
Create function <nom_fonction> [(liste d'arguments)] return 
typeRetourné  IS 
bloc PL/SQL ;
 La liste d'arguments est composée des arguments d'entrée, de 
sortie et d'entrée sortie séparés par une virgule selon le format 
suivant : 
Nom_argument {IN| OUT| IN OUT} type;
 Les types des paramètres sont les mêmes types utilisés en PL/SQL. 
 Pour les parametres de type chaine il faut s elimiter au type varchar 
sans indiquer la taille : procChaine (par1 in Varchar, par2 out 
varchar )
 Exemple : create procedure P1( par1 IN client.idclt%type,   par2  out 
commande.mntc%type, par3 integer ..) Is  .....
16/03/2021 Pr. Chaieb Chiheb  © 63
Paramètres /Arguments

 Ces arguments désignent en fait les paramètres


d'appel de la procédure ou la fonction. Ils
permettent de transférer des données entre la
procédure ou la fonction et l'environnement
appelant. Il existe trois modes de transfert :
 IN (valeur par défaut) indique que le paramètre
est passé en entrée, c'est la valeur du paramètre
qui sera passée de l'environnement appelant à la
procédure/fonction. Pour une fonction les
paramètres sont toujours passés dans ce mode.

16/03/2021 Pr. Chaieb Chiheb  © 64
Paramètres formels

 Le mode OUT permet à une procédure de


retourner une valeur dans le paramètre à
l'environnement appelant. La valeur est un
résultat calculé par la procédure. Nous pouvons
avoir plusieurs résultats envoyés par une
procédure.
 Le mode IN OUT est une combinaison de deux
méthodes : le paramètre est passé en entrée,
renseigné par la procédure puis renvoyer à
l'appelant comme résultat c'est le passage par
référence vu dans les langages classiques.

16/03/2021 Pr. Chaieb Chiheb  © 65
Application1: Création d’une Fonction
• Créer une fonction qui permet de retourner le reste à facturer ( avec TTC)   d'un client donné.  Ce montant 
est la différence entre le montant total de commandes  du client et le total des montants  de ses factures. 
Majorée avec une taxe. 
• Totfact  = Somme (MntFac) , TotCom = Somme(Mntc‐ Mntc*remise) 
• restAFact =  totCom – totFact * Taxe.  Taxe= 1.05% pour les clients R,  1.08%  pour les autres clients
• Entrées : code client , soit idCl client.idclt%type.  Résultat  : le reste à facture , soit resteAFact number    
Create or replace Function calculResteAFact (idCl in Client.idclt%type ) return number IS 
taxe number(4,2)  ;   tpCl client.typeC%type;
totCom commande.mntc%type;  
totFact totCom%type;  
resteAFact Facture.montFac %type;
Begin 
Select sum(mntc‐ mntc*remise) into totCom from  Commande where idclt= idCl ; 
Select sum (mntFac) into totFact from Facture where idclt=idCl ; 
select typeC into tpCl from client where idclt=idCl; 
If  (tpCl=‘R’  ) then 
taxe :=1.05; 
else taxe:=  1.08;  
end if; 
resteAFact := totCom‐ totFact*taxe ; 
Return resteAFact; 
End;
/6/03/2021
1 Pr. Chaieb Chiheb  © 66
Application‐Procédure
• Créer une procédure qui permet de baisser le prix d'un article donné d'un 
taux donné aussi.
Create or replace Procedure reduce price (cdart in number, taux in number) is 
Npu article.pu%type
Begin 
Select pu into npu from article where idart = cdart;
If npu <1000 then 
Update article  set  pu = pu‐ pu*taux  where idart= cdart;
Else
Update article  set  pu = pu‐ pu*taux*0.9  where idart= cdart;
End if;
Exception 
When no_data_found then 
Dbms_output.put_line(‘Article Inexistant’||cdart); ‐‐raise _application_error(‐
20001, 'Article ‘);
End;
/

16/03/2021 Pr. Chaieb Chiheb  © 67
Appel aux procédures /fonctions 

• En mode interactif
L'appel d'une fonction se fait par : 
Select nom_fonction(valeurs des paramètres) from dual;
Exemple: 
Afficher le résultat calculé par la fonction calc_ca() pour le client 
de code 1000/
Select calc_ca (1000) from dual; 

• Une procédure est appelée par la commande : 
Execute nom_proc( valeurs des paramètres ) 
Exemple : 
execute reduce_price(1, 0.05) ;

16/03/2021 Pr. Chaieb Chiheb  © 68
Appel aux procédures /fonctions 
• Dans un programme PL/SQL 
Considérant le programme PL/SQL suivant (prog1.sql) illustre 
l'appel à la procédure stockée reduce_price(). 
declare
x number: = 2;
y number: =100;
t number :=0.05;
begin
reduce price(x, t); ‐‐ appels à la procédure 
reduce price(y, t); ‐‐ appels à la procédure 
reduce price (25, t); ‐‐ appels à la procédure 
end;
/
16/03/2021 Pr. Chaieb Chiheb  © 69
Appel aux procédures /fonctions 

• Exercice : écrire une fonction Calc_Appro (idart) 
qui calcule la quantité d’approvisionnement d’un 
article : Qapp = ( Qstk ‐ Qmin)*f , f= 100   si 
TotQ_Vente> 10*Qmin, sinon f=50.  Calc_Appro
(idart).  TotQVente est le total des Qtés vendues 
de l'article,
• Développer un programme  PL/SQL qui fait  appel 
à cette fonction pour calculer la qteApp pour tous 
les articles dont le stock est épuisé.  Utiliser un 
curseur. 
16/03/2021 Pr. Chaieb Chiheb  © 70
Compilation, modification et suppression
• La commande : createprocedure/function nom_FP As 
[PL/SQL ] lance le processus de création de la 
procédure ou la fonction. Une phase d’interprétation 
de code se termine par une création de l’objet sans 
ou avec erreurs.  
• Pour visualiser les éventuelles erreurs syntaxiques : 
show errors function|procedure nom‐F
• Supprimer une fonction ou une procédure  :
drop function|procedure nomf;

16/03/2021 Pr. Chaieb Chiheb  © 71
User_Objects, User_procedures, User_Source
• User_Objects : table (vue) système du DD Oracle qui 
stocke (visualise) les objets BD utilisateurs : tables, 
séquences, index, vue, vue matérialisée , procedure, 
function, trigger etc.. : object_name, object_type ..
• User_procedures : procedure_name, id_object, ..
• User_source : vue permettant d’accèder au code source 
de l’objet (fonction, procédure ou trigger) :  name, type 
(trigger|function|procdure) , line, text
• Afficher le code source de la fonction calcApprov :
Select line,text from user_source where name = 
‘CAL_APPROV’ 
• Les noms des objets est stockés toujours en majuscule 
dans le DD d’oracle !!

16/03/2021 Pr. Chaieb Chiheb  © 72
Appel des Procedures en Java SE

16/03/2021 Pr. Chaieb Chiheb  © 73
JDBC : définition
• Java Data Base Connectivity (JDBC) : API de bas  niveau 
permettant de travailler avec une ou plusieurs   bases de 
données depuis un programme Java

• Objectif : interface uniforme assurant l’indépendance du 
SGBDR cible
• Versions :
– JDBC 1 : SDK 1.1 (java. SQL)
– JDBC 2 : SDK 1.2 (java SQL, javax.sql)
– JDBC 3 : SDK 1.4

16/03/2021 Pr. Chaieb Chiheb  © 74
JDBC : Architecture

16/03/2021 Pr. Chaieb Chiheb  © 75
Structure de l’application Java
1. Importation de paquetages 
(import java.sql.*/ import oracle.jdbc.driver/…
2. Enregistrement du pilote : Chargement de la classe 
du pilote
3. Établissement des connexions :
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection myCon=DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:orcl", 
"commercial","commercial");

16/03/2021 Pr. Chaieb Chiheb  © 76
Structure de l’application Java
4. Interfaces JDBC utilisables : 
 Interface Statement : pour les instructions 
SQL simples
 Interface PreparedStatement : pour les 
instructions SQL paramétrées           
 Interface CallableStatement : pour les 
procédures ou fonctions cataloguées (PL/SQL 
ou autres

16/03/2021 Pr. Chaieb Chiheb  © 77
Structure de l’application Java
 Ajouter le driver Oracle JDBC à votre Projet
 Allez dans les propriétés du projet et Ajouter le Jar fournis  

16/03/2021 Pr. Chaieb Chiheb  © 78
Structure de l’application Java
4.Interfaces utilisables  : CallableStatement
// Preparer l’appel à la procédure nommée myProc (par1 in  
varchar, par2 out integer )  
CallableStatement myStmt = myConn.prepareCall ("{ call 
myProc (?, ? ) } " );
Préparation de l appel procédure

// initialiser les paramètres de la procédure
myStmt.setString (1, ‘une chaine pour par1’);
myStmt.registerOutParameter(2,TYPE.INTEGER) ;
Insertion de paramètres d’entrée 
et de paramètres  sortie 

16/03/2021 Pr. Chaieb Chiheb  © 79
CallableStatement : exemple2

16/03/2021 Pr. Chaieb Chiheb  © 80
Appel de procédure et établissement 
de connexion 

16/03/2021 Pr. Chaieb Chiheb  © 81
Insertion des paramètres et Exécution des procédures

callStmt.setString (1, ‘Tunis’); 
callStmt.setInt(2, 500);
callStmt.registerOutParameter (3, 
java.sql.Types.INTEGER);  
callStmt.execute();
nbPilotePrimes=callStmt.getInt(3);
callStmt.close();          

16/03/2021 Pr. Chaieb Chiheb  © 82
package main;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection 
myCon=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl
", "commercial","commercial");
System.out.println(" Connexion sur la BD ok");
DatabaseMetaData dbmd = myCon.getMetaData();  
System.out.println("Driver Name: " + dbmd.getDriverName());
16/03/2021 Pr. Chaieb Chiheb  © 83
System.out.println("Driver Version: " + dbmd.getDriverVersion());
System.out.println("schema : "+dbmd.getUserName() );

String prepCall = "{ call calcul_App (?, ? ) } ";


CallableStatement callStmt =myCon.prepareCall(prepCall);
callStmt.setInt(1,1) ;   // affecter la valeur 1 au premier paramètre idart
callStmt.registerOutParameter(2,java.sql.Types.INTEGER); 
// deuxieme parametre resultat
callStmt.execute()  ; // exécution de la requête 
int qapp = callStmt.getInt(2);
callStmt.close();
System.out.println("Quantité Approvisionnment calculée : "+qapp);
} catch(SQLException|ClassNotFoundException e){
((Throwable) e).printStackTrace();
System.out.println("Problème Connexion sur la BD "+e.getMessage());       
}}

16/03/2021 Pr. Chaieb Chiheb  © 84
}
Appel aux fonctions 
Supposons qu’on dispose d’une fonction calcul(ida in 
article.idart%type) qui retourne la quantité d’appro de type 
integer d’un article dont l’id est donné. 
L’appel à la fonction calcul en java se fait comme suit : 
String prepCall = "{ ?= call calcul(?) } ";
CallableStatement callStmt =myCon.prepareCall(prepCall);
callStmt.registerOutParameter(1,Types.INTEGER);  // resultat
retourné ets double
callStmt.setInt(2,10);   // calcul de qte appp pour article 10 
callStmt.execute(); 
qapp = callStmt.getInt(1);
callStmt.close();
System.out.println("Quantité Approvisionnment calculée par la 
fonction : "+qapp);

16/03/2021 Pr. Chaieb Chiheb  © 85
Exercice
1. Développer une procédure stockée nommée 
chiffAff (idclt in client.idclt %type, chiff out 
number, nbrfac out integer )  qui calcule le chiffre 
d’affaire du client et le nombre de ses factures. Le 
chiffre d’affaire est la somme de montant 
factures du client. 
2. Développer une application java SE qui  appelle 
cette procédure pour calculer le chiff d’affaire et 
le nombre des factures d’un client donné. 

16/03/2021 Pr. Chaieb Chiheb  © 86
Les Triggers de Base de Données

16/03/2021 Pr. Chaieb Chiheb  © 87
Les Triggers de Base de Données 
Définition
 Un trigger (appelé déclencheur) est une procédure stockée
particulière qui s’exécute automatiquement par oracle en
réponse à un événement spécifique qui se réalise.
 Un trigger est :
 une procédure stockée écrite en PL/SQL (possible aussi
avec Java ! )
 associé à une seule table.
 stocké dans la base.
 implicitement déclenché par Oracle lorsqu’une opération
INSERT, UPDATE, DELETE a lieu sur la table associée
 il est opérationnel jusqu’à la suppression de la table à
laquelle il est lié.

16/03/2021 Pr. Chaieb Chiheb  © 88
Les Triggers de Base de Données 

 A partir de la version 9i,  un trigger peut être 
aussi déclenché : 
 Pour les événements sur la base ou le schéma
(démarrer, arrêter, créer un objet schéma,…).
 Pour les événements d’utilisateur (connecter,
Déconnecter )

16/03/2021 Pr. Chaieb Chiheb  © 89
Les Triggers de Base de Données 

16/03/2021 Pr. Chaieb Chiheb  © 90
Les Triggers de Base de Données 

Usages
• Spécifier et maintenir des règles de gestion
complexes.
• Générer automatiquement des valeurs dérivées
des colonnes (valeurs clé auto générée, ..)
• Réaliser un traitement automatisé (calcul, maj,..)
• Éviter des transactions non‐valides.
• Modifier des données sur les tables lorsqu’elles
sont mises à jour dans les vues.
16/03/2021 Pr. Chaieb Chiheb  © 91
Structure d'un Trigger 

 Nom du trigger
 CREATE [OR REPLACE] TRIGGER <nom> , « REPLACE » : re‐créer
la définition du trigger
 Temps de déclenchement
 BEFORE | AFTER : Déclencher avant ou après un événement.
 Événement(s) déclenchant(s)
 INSERT OR UPDATE [OF <colonnes>] OR DELETE ON
<table>
 Événement simple : INSERT, UPDATE, DELETE.
 Combinaison des événements en utilisant le connecteur
logique OR.
 UPDATE OF <colonnes> : seules modifications sur les
colonnes spécifiées peuvent déclencher ce trigger.

16/03/2021 Pr. Chaieb Chiheb  © 92
Structure d'un Trigger 

 Niveau du Trigger : FOR EACH ROW


Niveau du trigger
 Tuple « FOR EACH ROW »: le trigger est exécuté pour
chaque tuple affecté.
 Table (par défaut): le trigger n’est exécuté qu’une seule
fois, sans considérer le nombre de tuples modifiés.
 Restriction (pour type « FOR EACH ROW »)
 WHEN (<condition>) , utilisée avec FOR EACH ROW
<Condition> : une expression logique dont le résultat doit
être vrai pour que le trigger soit déclenché.
 Corps du trigger :
 Un bloc PL/SQL ou un appel d’une procédure stockée.

16/03/2021 Pr. Chaieb Chiheb  © 93
Type de Trigger (ligne, table)

 Les triggers de BD se déclenchent suite à une action de mise à


jour (INSERT, DELETE, UPDATE) sur une table indiquée.
 Le traitement associé au trigger est exécuté:
 Soit une seule fois suite à un ordre lmd qui a touché plusieurs
lignes (trigger niveau table)
 Soit pour chaque ligne de la table concernée par l’événement
(trigger ligne) l'option for each qui est spécifiée dans la création.
 Un trigger ligne est exécuté pour chacune des lignes sur
laquelle l'ordre LMD est exécuté.
 Un trigger niveau table s’exécute une seule fois même si
l’événement affecte plusieurs lignes. Les références NEW ou
OLD sont interdites dans les déclencheurs niveau table.

16/03/2021 Pr. Chaieb Chiheb  © 94
Syntaxe Création d’un trigger
Trigger Table : Create trigger  nomTrigger {before | after}  {delete 
| insert| update [of colonne [, colonne] ..] }  On  nomTable
block PL/SQL  
Trigger  niveau ligne  :   Create trigger nomTrigg {before | after}  
{delete | insert| update [of colonne [, colonne] ..] }  On nomTable
for each row
block PL/SQL
 Le block PL/SQL décrit les actions menées par le trigger :
Comporte des requêtes SQL et/ou des instructions PL/SQL. Sauf :
– Instructions de définition de données (DDL) comme CREATE, 
DROP, ALTER.
– Instructions de contrôle d’une transaction comme COMMIT ou 
ROLLBACK, SAVEPOINT

16/03/2021 Pr. Chaieb Chiheb  © 95
Création d’un trigger

La clause when : le trigger se déclenche sur l'ordre de


mise à jour associé mais sous certaine condition ,
dans ce cas malgré la production de l'événement
déclencheur, la condition doit être vérifiée pour que le
trigger s'exécute.
L'option after spécifie que les actions du trigger sont
exécutées après l’action de mise à jour sur la table
associée à l'événement, alors que pour l'autre option
before, le trigger s’exécute avant l’action de mise à
jour sur la table.

16/03/2021 Pr. Chaieb Chiheb  © 96
Références New et Old

 Valables pour uniquement les triggers niveau


Ligne
La référence ':new' désigne le nouveau tuple
ajouté dans la table suite à une action d’insertion
ou de modification,
La référence ':old‘ désigne l'ancien tuple qui vient
d'être supprimé ou modifié suite à une action de
suppression ou de modification.
Ces deux références sont accessible par le trigger
ligne, le champ de la ligne est référencé par
:old.idChamp , :New.idChamp.
16/03/2021 Pr. Chaieb Chiheb  © 97
raise_application_error

Pour gérer les erreurs dans un trigger utiliser la


procédure «raise_application_error »
Est le seul moyen de faire « rollback » la
transaction en cours.
Lorsqu’elle est exécutée, elle arrête le trigger,
retourne un chiffre représentant l’erreur et refait
toutes les modifications effectuées auparavant
(dans la même transaction).
Le chiffre d’erreur peut être de –20999 à –20000,
choisie arbitrairement par le programmeur.

16/03/2021 Pr. Chaieb Chiheb  © 98
Exemple raise_application_error

Interdire la diminution du salaire d'un employé s'il avance


dans l'échelle (echelle nouveau > échelle ancien)
Employe (mat, name, echelle, salBase …)
CREATE OR REPLACE TRIGGER verif_salaire Before UPDATE
OF echelle ON Employe FOR EACH ROW
WHEN (new.echelle > old.echelle )
BEGIN
IF :new.salaireBase < :old.salaireBase THEN
RAISE_APPLICATION_ERROR(‐20002,’diminution salaire
interdite ‘);
END IF;
END
16/03/2021 Pr. Chaieb Chiheb  © 99
Prédicats Conditionnels  

 En cas de combiner plusieurs événements, utiliser 
des INSERTING, DELETING, UPDATING pour 
exécuter des blocs spécifiques correspondant.
 If (inserting ) then
traitement envisagé an cas d'un evenement insert
 If (updating) then
traitement envisagé an cas d'un evenement insert
 If (deleting) then
traitement envisagé an cas d'un evenement delete

16/03/2021 Pr. Chaieb Chiheb  © 100


Exemple des triggers

Créer un trigger qui interdit la MAJ de la table


Pilote par les users autre que ISA1.
Créer un trigger qui actualise le stock article
chaque fois qu’une ligne livraison est ajoutée
ou supprimée :
 Livraison (idLiv, dateLiv, adrLiv, idclt#)
 DetailLiv (idLiv, idart, qteLiv)
 Article (idArt, desArt, qteStk, Pu, tva)

16/03/2021 Pr. Chaieb Chiheb  © 101


Trigger table

16/03/2021 Pr. Chaieb Chiheb  © 102


Trigger Ligne 
Create trigger trigDetaiLiv after insert or delete on 
detailLiv for each row
Declare 
Begin
If deleting then 
….
End if;
If  inserting then 
….
End if;
End;
/
16/03/2021 Pr. Chaieb Chiheb  © 103
Actions sur les Triggers

 Création  : Create trigger 
 Suppression : Drop trigger tigName;
 Activation – désactivation d’un trigger :       
Alter Trigger trigName enable/disable
 Recompilation du code de création de trigger, suite à 
une modification sur la structure de la base de 
données ou : Alter trigger <nom_trig> compile ;

16/03/2021 Pr. Chaieb Chiheb  © 104


Attributs des Triggers

• Des informations générales sur les triggers sont stockées dans les
vues suivantes du dictionnaire de données :
– USER_TRIGGERS
– DBA_ TRIGGERS.
– Comme Informations, nous pouvons indiquer :
– Trigger_name, Table_name, column_name
– Trigger_type : before ou after
– Triggering_event : action de maj associée (insert, update, delete
)
– Description : entête de trigger, name, type, evenement et la
table
– Status : état (enable/disable)
– trigger_body : code PL/SQL

16/03/2021 Pr. Chaieb Chiheb  © 105


Utilisation des trigger

1. Trigger Ordinaire : Exemples Précédents


2. Trigger de contrôle de MAJ d’une table / colonne
Un trigger qui contrôle la saisie des commandes en
interdisant la saisie d’une commande dont la date
est en dehors de l’intervalle date de jour système,
date de jour – 2.
3. Trigger de définition de contrainte d’intégrité
complexes :
Date de Livraison est > date de Commande +1
Date résiliation Contrat Ass > date de Jour + 1
Interdiction de création des articles par l’user autre que
Commercial;
4. Trigger d’audit
16/03/2021 Pr. Chaieb Chiheb  © 106
Utilisation des trigger

On peut définir plusieurs triggers de même  type.
S’il y a plusieurs triggers de même type, l’ordre 
d’exécuter sera arbitraire.
Un trigger défini sur  une table, ne peut pas agir 
(ordre de maj) sur la même table. 

16/03/2021 Pr. Chaieb Chiheb  © 107


Fonction Sys_Context (userEnv, paramètre)

• SYS_CONTEXT(userEnv, paramètre)  renvoie la valeur du 
paramètre associé à l'espace de noms de contexte (userEnv). Elle 
est utilisable en SQL et PL / SQL.  
• Example : SELECT SYS_CONTEXT ('USERENV', ‘session_user') 
FROM DUAL; affiche le nom de l’user BD. 
 Autres paramètres  : 
 Os_user : nom de l’user de point de vue système client,
 Db_name : nom de la bd oracle (orcl)
 CURRENT_SCHEMA : schéma courant instantané
 Host : nome de la machine client (nom sur le réseau)
 Instance_name :  l’instance sur laquelle l’user est connecté
 Ip_adress : adresse ip de la machine client

16/03/2021 Pr. Chaieb Chiheb  © 108


Applications

Créer un trigger qui contrôle la saisie des


commandes en interdisant la saisie ou la maj
(datec) d’une commande dont la date est >= Dj et
< Dj – 2.
Créer un trigger de table interdisant la maj ou la
supression d’une commande facturée ou livrée
sauf son état
Créer un trigger qui interdit l’ajout d’une livraison
dont la commande n’est pas encore facturée, de
même l’ajout d’une livraison ne doit se faire que
par l’user ‘Commercial’.
16/03/2021 Pr. Chaieb Chiheb  © 109
Eléments de Correction

Q1 :
Create or replace trigger VerifCommande before
Insert or update of datec on Commande for each
row
Begin
If :new.datec not between sysdate and sysdate‐2
then
Raise_Applicaton_Error (‐20010, ‘date commande
invalide ’);
End if;
End;
16/03/2021 Pr. Chaieb Chiheb  © 110
Eléments de Correction

Q2:
Create or replace trigger VerifCommande2 before delete
or update of idclt,mntc,remise,datec on Commande for
each row
Begin

if :old.etatc > 1 then


Raise_Applicaton_Error (‐20012, ‘commande facturée
ou livrée MAJ non autorisée ’);
End if;

End;

16/03/2021 Pr. Chaieb Chiheb  © 111


Eléments de Correction
Q3 :
Create or replace trigger VerifLiv before Insert on Livraison for each
row
Vetatc commande.etatc%type;
Begin
If user != ‘commercial’ then
Raise_Applicaton_Error (‐20001, ‘User non Autorisé ’);
Else
Select etatC into vetatC from commande where numc=:new.numc;
If etatC!=1 then
raise_application_error (‐20001, ‘Commande Non encore Facturée ’);
End if;
End if;

16/03/2021 Pr. Chaieb Chiheb  © 112


FIN 

Merci pour Votre Attention ..............

16/03/2021 Pr. Chaieb Chiheb  © 113


Références 

1. https://www.lri.fr/~fiorenzi/Teaching/BDAS/C2.pdf
2. http://sql.bdpedia.fr/plsql.html
3. https://www.uv.es/nemiche/cursos/polycopies/7%20Programmation%20PL‐
SQL%20Oracle.pdf
4. https://perso.liris.cnrs.fr/emmanuel.coquery/dokuwiki/lib/exe/fetch.php?media=enseignem
ent:fc:fc‐05‐pl‐sql.pdf
5. https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions184.htm#g1513460

16/03/2021 Pr. Chaieb Chiheb  © 114

Vous aimerez peut-être aussi