Académique Documents
Professionnel Documents
Culture Documents
PL SQL
PL SQL
LE LANGAGE PL/SQL
1 / INTRODUCTION :
SQL est un langage complet pour travailler sur une base de donnée relationnelle, mais il ne
comporte pas des instructions procédurales. PL/SQL comprend quant à lui :
PL/SQL n'interprète pas une commande, mais un ensemble de commandes contenues dans un
programme ou bloc PL/SQL.
La structure d’un bloc est la suivante:
DECLARE
Déclarations de variables, constantes, exception;
BEGIN
Section obligatoire contenant des instructions SQL et PL/SQL ou des blocs fils (Possibilités
d’imbrication de blocs)
EXCEPTION
Traitement des exceptions (gestion des erreurs)
END;
REMARQUES :
Les sections Declare et Exception sont optionnelles
Chaque instruction de n’importe quelle section doit se terminer par un ‘ ;’
DECLARE
qte_stock number(5);
BEGIN
Select quantite into qte_stock from PRODUITS
where codprod= ‘p1’;
La partie déclarative dans un bloc PL/SQL, peut comporter trois types de déclarations. Elle
est délimitée par les mots-clé :
v DECLARE, qui spécifie le début de la déclaration des variables et
v BEGIN, qui signifie la fin de la déclaration et le début de la partie des commandes.
v Les types de déclarations possibles dans cette partie sont les suivants :
ü déclaration des variables et des constantes,
ü déclaration de curseurs,
ü déclaration des exceptions.
3.1 Types de données
Chaque variable ou constante utilisée dans un bloc PL/SQL, possède un type de données.
PL/SQL offre deux variétés de types de données prédéfinies : scalaire et composé.
La déclaration d'une variable consiste à allouer un espace pour stocker et modifier une valeur.
elle est typée et peut recevoir une valeur par défaut et/ou un statut NOT NULL.
Une constante est définie comme une variable, mais l'utilisateur ne peut pas modifier son
contenu.
Les variables se définissent dans la partie DECLARE, du bloc PL/SQL en utilisant la syntaxe
suivante :
nomvariable [CONSTANT]
{type | variable%TYPE | colonne_de_table.%ROWTYPE}
[NOT NULL]
[{ :=|DEFAULT} expression PL/SQL]
Remarques :
L'attribut CONSTANT permet de figer l'affectation d'une variable.
L'attribut Not NULL rend obligatoire d'initialiser la variable lors de sa définition.
On peut faire référence à une colonne d'une table par la déclaration :
♦ nom_variable TABLE.COLONNE%TYPE,
On peut faire référence à une ligne d'une table par la déclaration
♦ Nom_variable TABLE%ROWTYPE,
On peut faire référence à une variable précédemment définie par l'instruction
♦ Nom_variable Pnom variable%TYPE
♦ 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.
Les variables peuvent également être définies dans l'environnement extérieur au Bloc PL/SQL
par exemple comme des champs de l'écran en Form Builder. Ces variables seront utilisées
préfixées de':'.
On peut déclarer un type TABLE dans la partie déclarative d'un bloc ou d'un sous-programme
en utilisant la syntaxe suivante :
Lorsque le type est déclaré, on peut déclarer des tableaux de ce type de la façon suivante :
Nom_tab nom_type ;
Nom_tab(valeur_clé_primaire) ;
Pour affecter la valeur d'une expression PL/SQL à un élément du tableau, on doit utiliser la
syntaxe suivante :
nom_tab(valeur_clé_primaire) := expression_Pl/sql ;
Exemple :
DECLARE
tab_nom nom_tab_type ;
BEGIN
…
tab_nom(l):='TUNISIE';
…
END;
Comme les tableaux PL/SQL, la déclaration d'un enregistrement se fait en deux étape
On peut déclarer un Type RECORD dans la partie déclarative d'un bloc ou d'un sous-
programme en utilisant la syntaxe suivante:
Lorsque le type est déclaré,On peut déclarer des enregistrements de ce type de la façon
suivante :
Nom_erg nom_type ;
Exemple :
DECLARE
TYPE ADRESSE IS RECORD
(Numero positive,
Rue varchar2(35),
CodePost char(5),
Ville varchar2(25),
Pays varchar2(30) );
TYPE CLIENT IS RECORD
(NumCIi positive,
NomCli varchar2(40),
Adrcli ADRESSE,
CA number(12,3));
monclient CLIENT ;
BEGIN
monclient.NumCIi := 1234;
monclient.NomCIi := ‘Ben HUSSEIN’;
monclient.AdrCli.Numero := 10;
END ;
4 STRUCTRES DE CONTROLE
4.1. Les traitements Conditionnels
IF condition_plsql
THEN commandes
[ELSE commandes]
[ELSIF condition_plsql
THEN commandes
[ELSE commandes]]
END IF;
La condition peut utiliser les variables définies ainsi que tous les opérateurs présents dans
SQL =,<,>,<=,>=,<>, IS NULL, IS NOT NULL.
Exemple :
DECLARE
vjob CHAR(10);
vnom employés.ename%type := ‘BEN SALAH’ ;
msg CHAR(30) ;
BEGIN
Select job into vjob from employés where ename = vnom;
Syntaxe :
LOOP
instructions
END LOOP ;
DECLARE
somme number(10) := 0 ;
nombre number(5);
BEGIN
nombre:=0;
LOOP
Nombre:=nombre+1 ;
somme := somme + nombre ;
if nombre>=10
then EXIT;
end if ;
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘la somme des 10 premiers entiers est ‘ || to_char(somme));
END;
instructions
END LOOP ;
compteur. est une variable de type entier, locale à la boucle. Sa valeur de départ est égale par
défaut à la valeur de l'expression entière de gauche (var_debut). Elle s'incrémente de 1, après
chaque traitement du contenu de la boucle, jusqu'à ce qu'elle atteigne la valeur de droite
(var_fin).
v Le curseur implicite
Il est généré et géré par le noyau pour les autres commandes SQL.
L’utilisation d'un curseur pour traiter un ordre Select ramenant plusieurs lignes, nécessite 4
étapes:
1. Déclaration du curseur
2. Ouverture du curseur
3. Traitement des lignes
4. Fermeture du curseur.
Exemple :
Declare
Cursor DEPT_10 is
select ename, sal from emp where depno = 10;
La syntaxe :
Exemple :
Begin
…
OPEN DEPT_10
/* traitement des lignes*/
CLOSE DEPT_10
La syntaxe :
Dans la partie traitement du bloc.PL/Sql, il faut commencer par ouvrir le curseur puis
L’ordre fetch ne ramène qu’une seule ligne à la fois. De ce fait il faut recommencer l’ordre
pour traiter la ligne suivante.
Exemple :
Declare
Cursor DEPT_10 is
select ename, sal from emp where depno = 10;
Vnom emp.name%TYPE ;
Vsalaire emp.sal%TYPE ;
Begin
OPEN DEPT_10;
LOOP
FETCH DEPT10 into vnom,vsalaire ;
--Traitement ligne
END LOOP ;
CLOSE DEPT_10;
End;
5.4 Les attributs d’un curseur
Les attributs d’un curseur nous fournissent des informations sur l’exécution d’un ordre. Ils
sont conservés par PL/SQL après l’exécution du curseur (implicite ou explicite)
Ces attributs permettent de tester directement le résultat de l’exécution. Ils sont résumés dans
le tableau suivant :
Declare
CURSOR num_cur1 IS SELECT num from tab1 ;
CURSOR num_cur2 IS SELECT num from tab2 ;
Num1 number ;
Num2 number ;
somme number := 0;
Begin
OPEN num_cur1 ;
OPEN num_cur2 ;
LOOP
FFTCH num_cur1 INTO num1 ;
FFTCH num_cur2 INTO num2;
IF (num_cur1%Found) AND (num_cur2%Found) THEN
somme:= num1 + num2 ;
INSERT INTO sum_tab VALUES (somme);
ELSE
Exit ;
END IF;
END LOOP;
CLOSE numl_cur1 ;
CLOSE mun_cur2 ;
COMMIT;
END;
Exemple :
Declare
CURSOR num_cur1 IS SELECT num from tab1 ;
CURSOR num_cur2 IS SELECT num from tab2 ;
Num1 number ;
Num2 number ;
somme number := 0;
Begin
OPEN num_cur1 ;
OPEN num_cur2 ;
LOOP
FFTCH num_cur1 INTO num1 ;
FFTCH num_cur2 INTO num2;
EXIT WHEN (num_cur1%NotFound) OR (num_cur2%NotFound) ;
somme:= num1 + num2 ;
INSERT INTO sum_tab VALUES (somme);
END LOOP;
CLOSE numl_cur1 ;
CLOSE mun_cur2 ;
END;
Declare
Cursor Dept10 is
Select ename, sal from emp where deptno=10;
Begin
If not (Dept10%lsopen) then
open Dept10 ;
End if,
Fetch Dept10 into …
--traitement
End ;
5.4.4.'L'attribut %RowCount
Cet attribut est de type numérique. Le curseur implicite indique le nombre de lignes traités par
les ordres insert, update, delete.
Le curseur explicite est incrémenté à chaque ordre fetch, donc cet attribut traduit la nième
ligne traitée.
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 Cl;
Loop .
Fetch cl into nom, numéro, salaire ;
exit when (c1%rowcount > 25) or (cl%notfound);
insert into temp values (salaire, numéro, nom);
End Loop;
Close C1 ;
commit ;
End;
Syntaxe :
Dans la partie déclarative du bloc.
Exemple
Declare
/* la fonction nvl permet de tester la valeur Null d'une colonne si comm=NULL alors nvl
retourne 0 sinon nvl retourne la valeur de comm */
Begin
open c1;
Loop
Fetch c1 into c1_record;
Exit when c1 %notfound ;
Declare
Cursor nomcurseur is ordre_select ;
Begin
For nomrecord in nomcurseur Loop
/* traitement
End Loop;
End;
Le bloc PL/SQL ci-dessus permet d'obtenir une génération implicite de la structure suivante :
Declare
Cursor nomcurseur is ordre_select;
nomrecord nomcurseur%rowtype;
Begin
Open nomcurseur ;
Loop
Fetch nomcurseur into nomrecord ;
Exit when nomcurseur%notfound ;
/* traitement
End Loop;
Close nomcurseur;
End;
Begin
Open nomcurseur (valeurl , vaieur2, ....) ;
Exemple :
Declare
cursor c1 (depart number)
is select sal, nvl(comm,0) 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
total:= total+ c1_rec.sal + c1_rec.commi ;
if c1_rec.sal > 4000
then sal_sup := sal_sup + 1 ;
end if ;
if c1_rec.commi > 3000
then commi_sup:=commi_sup+1 ;
end if;
End Loop;
insert into temp
values (sal_Sup, comm_sup, 'total salaire’||to_Char(total));
commit ;
End;
Declare
Cursor cl is select ename, sal from emp
for update of sal ;
Begin
For c1_record in c1 Loop
If c1_ record.sal > 1500 then
insert into resultat values (c1_record.sal, c1_record.sal*1.3, c1_record.ename);
update emp set sal = sal * 1.3 where current of c1 ;
end if,
End loop ;
Commit;
End ;
6 Utilisation de sous-programmes
PL/SQL accepte aussi l’utilisation de sous-programmes, nommés procédures et fonctions.
Une procédure PL/SQL exécute certaines actions et peut accepter des paramètres optionnels.
Une fonction PL/SQL retourne une valeur d’un certain type et peut aussi accepter des
paramètres optionnels.
Exemple :
Declare
Vpatient_ID Patient.Patient_ID%type ;
Fièvre_elevée constant real := 42 ;
Exemple :
Soit l’extrait suivant d’une base de données relationnelle d’une application de gestion de
scolarité d’une université :
Etudiant(codetu, nometu,adretu)
Matière(codmat, description_mat, coefmat)
Moyenne(codetu,codmat, moyenne_mat)
Declare
Codmatière Matière.codmat%type;
Vcode_etu etudiant.codetu%type;
FUNCTION meilleur_étu_mat (pcodmat varchar2) RETURN varchar2 IS
Vcodetu etudiant.codeetu%type ;
BEGIN
Declare
Param1 number ;
Param2 number ;
Param3 number ;
Procedure Différents_Param(P1 IN number, P2 OUT number, P3 IN OUT number) Is
Begin
P2 := P1 ;
P3 := P3 + 1 ;
END ;
Begin
Param1 := 3.14 ;
Param3 := 15 ;
Différents_Param(Param1, Param2, Param3) ;
DBMS_OUTPUT.PUT_LINE('param1 = ' || to_char(param1) || 'param2 = ' ||
to_char(param2) ||
'param3 = ' || to_char(param3) );
End ;
1. Erreur interne Oracle (Sqlcode <= 0) : dans ce cas la main est rendue directement au
système environnant.
2. Anomalie déterminée par 1'utilisateur.
La solution :
1. Donner un nom à l'erreur (si elle n'est pas déjà prédéfinie),
2. Définir les anomalies utilisateurs, leur associer un nom,
3. Définir le traitement à effectuer.
Pour gérer les exceptions le programmeurdoit écrire un gestionnaire des exceptions qui prend
le contrôle du déroulement du bloc PL/SQL en présence d'une exception.
Le gestionnaire d'exception fait partie du bloc PL/SQL et se trouve après les commandes Il
commence par le mot clé EXCEPTION et se termine avec le même END du bloc.
Chaque gestion d'exception consiste à spécifier son nom d'erreur après la clause WHEN et la
séquence de la commande à exécuter après le mot clé THEN, comme le montre l'exemple
suivant:
DECLARE
Wsal emp.sal%type;
BEGIN
select sal into wsal from emp;
EXCEPTION
WHEN TOO_MANY_ROWS then…
--gérer erreur trop de lignes
WHEN NO_DATA_FOUND then…
--gérer erreur pas de ligne
WHEN OTHERS then…
--gérer toutes les autres erreurs
END ;
Remarques :
DECLARE
Nom_ano Exception;
2. Déterminer l’erreur et passer la main au traitement approprié par la commande Raise.
BEGIN
…
If (condition_anomalie) then raise Nom_ano
3. Effectuer Ie traitement défini dans la partie EXCEPTION du Bloc.
EXCEPTION
WHEN (Nom_ano) then (traitement);
Exemple :
DECLARE
wsal emp.sal%type ;
sal_zero Exception ;
BEGIN
Select sal into wsal from emp where empno=5;
If wsal=0 then
Raise sal_zero;
EXCEPTION
WHEN sal_zero then…
-- gérer erreur salaire
WHEN TOO_MANY_ROWS then...
--gérer erreur trop de lignes
WHEN_NO_DATA_FOUND then ...
-- gérer erreur pas de ligne
WHEN OTRERS then ...
--gérer toutes les autres erreurs
END;
Le programmeur Peut utiliser les fonctions Sqlcode et Sqlerrm pour coder les erreurs Oracle
en Exception.
sqlcode est une fonction propre à PL/SQL qui retourne le numéro (généralement négatif)
de l'erreur courante.
Sqlerrm reçoit en entrée le numéro de l'erreur et renvoie en sortie le message de l'erreur codé
sur196 octets.