PL/SQL
PL/SQL est le langage procédural de troisième génération (L3G), extension du SQL, finement intégré au serveur Oracle . Il permet de manipuler toutes les données Oracle : relationnelles, relationnelles-objet, Java. C’est un langage de programmation à la fois puissant, simple et moderne destiné à exprimer facilement vos règles de gestion complexes sous forme de procédures et de triggers stockés.
Les avantages de PL/SQL
Intégration parfaite du SQL :SQL est devenu
le langage d’accès aux bases de données parce
qu’il est standard, puissant. De très nombreux
outils en ont popularisé l’utilisation. PL/SQL
permet de réaliser des traitements complexes sur
les données contenues dans une base Oracle
d’une façon simple, performante et sécurisée.
Support de la programmation orientée objet :
Les types objet proposent une approche aisée et
puissante de la programmation objet. En
encapsulant les données avec les traitements, ils
offrent au PL/SQL une programmation qui
s’appuie sur des méthodes. Dans la
programmation objet, l’implémentation des
méthodes est indépendante de leur appel, ce qui
constitue un avantage. On peut ainsi modifier des
méthodes sans affecter l’application cliente.
Très bonnes performances : Ce ne sont plus des ordres SQL qui sont transmis un à un au moteur de base de données Oracle , mais un bloc de programmation. Le traitement des données est donc interne à la base, ce qui réduit considérablement le trafic entre celle-ci et l’application. Combiné à l’optimisation du moteur PL/SQL, cela diminue les échanges réseau et augmente les performances globales de vos applications. Le moteur PL/SQL d’Oracle a été optimisé et les performances de traitement sont accrues.
Portabilité : Toutes les bases de données Oracle comportent un moteur d’exécution PL/SQL.
Comme Oracle est présent sur un très grand nombre de plates-formes matérielles, le PL/SQL permet une grande portabilité de vos applications.
Facilité de programmation : PL/SQL est un langage simple d’apprentissage et de mise en œuvre. Sa syntaxe claire offre une grande lisibilité en phase de maintenance de vos applications. De nombreux outils de développement, autres que ceux d’Oracle , autorisent la programmation en PL/SQL dans la base de données.
Parfaite intégration à Oracle et à Java : PL/SQL, le langage L3G évolué, est étroitement intégré au serveur Oracle. Il est également possible d’utiliser Java à la place de PL/SQL. Partout où PL/SQL peut être employé, Java peut l’être aussi. Java permet d’aller au- delà des possibilités de PL/SQL.
Oracle Application Express utilise massivement le PL/SQL : Oracle Application Express est une solution de développement d’applications Web à contenu dynamique. L’interface de développement et l’application utilisent des pages Web écrites en langage HTML. Oracle Application Express cible les applications Internet à développement rapide et à déploiement simplifié. Dans son fonctionnement interne, Application Express utilise massivement le langage PL/SQL.
Survol de PL/SQL : Une manière simple d’aborder le PL/SQL est d’observer quelques-unes des utilisations qui en sont faites.
-- PL/SQL Exemple
DECLARE
v_salaire NUMBER(7);-- variable locale BEGIN
SELECT sal INTO v_salaire FROM emp WHERE ename = ‘EMP1’
FOR UPDATE OF sal;
IF v_salaire < 1000 THEN -- test sur le salaire UPDATE emp SET sal = sal*1,1
WHERE ename = ‘SCOTT’; -- augmentation de 10%
ELSE
UPDATE emp SET comm = comm + 100 WHERE ename = ‘EMP1’ ;
END IF;
COMMIT;
Ici, le langage SQL permet de rechercher et de mettre à jour des données tout en contrôlant les modifications apportées suivant les conditions exprimées par le PL/SQL. Le langage SQL est « ensembliste », c’est-à- dire qu’il ne manipule qu’un ensemble de données satisfaisant des critères de recherche. PL/SQL est « procédural » il permet de traiter de manière conditionnelle les données retournées par un ordre SQL. Vous ne pourriez pas résoudre aussi simplement, en SQL « pur », un traitement tel que celui de l exemple.
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. Les sections indispensables d’un bloc sont le BEGIN et le END.
Elles peuvent être précédées d’une zone 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;
Les variables PL/SQL : PL/SQL permet de déclarer des variables et des constantes, puis de les utiliser dans des ordres SQL ou des traitements. Seul impératif président à l’utilisation d’une variable : elle doit d’abord être déclarée. Cette déclaration s’effectue dans la zone DECLARE.
DECLARE
v_texteVARCHAR(30);
BEGIN ...
v_texte := ‘Texte que je manipule.’;
...
END;
Les structures de contrôle : C’est l’une des plus importantes caractéristiques de PL/SQL. Ces structures permettent de contrôler l’exécution des ordres SQL et de traiter de façon procédurale les données.
Les principales structures sont les suivantes :
● IF-THEN-ELSE ;
● FOR-LOOP ;
● WHILE-LOOP ;
● EXIT-WHEN ;
• GOTO (peu utilisé).
Les curseurs : Oracle utilise des espaces de travail pour exécuter les ordres SQL et en manipuler les données. Une instruction PL/SQL, le curseur, permet d’attribuer des noms à ces espaces de travail et d’accéder aux données contenues. Il existe deux sortes de curseurs : les curseurs implicites et explicites. Le PL/SQL crée de manière implicite un curseur pour chaque ordre SQL, même pour ceux qui ne renvoient qu’une ligne. Pour les curseurs qui renvoient plus d’un enregistrement, vous pouvez déclarer explicitement un curseur, afin de manipuler individuellement les lignes retournées.
La modularité : PL/SQL permet d’écrire des programmes modulaires, faciles à réaliser et à maintenir. On peut scinder un problème complexe en un ensemble de sous-programmes simples, grâce aux procédures et aux fonctions. Par-delà les blocs et leurs sous-programmes, PL/SQL propose les PACKAGES, qui permettent de regrouper un ensemble de programmes liés sous une même appellation, avec une partie « privée » (accessible uniquement par les procédures et fonctions internes au package) et une partie « publique » (accessible par les procédures et fonctions externes au package).
Les attributs : Cette possibilité est fort utile. Elle fait référence aux caractéristiques d’une colonne de table (par exemple) et d’en récupérer automatiquement le type. Si le schéma de la base de données se trouve modifié (zone textuelle augmentée, zone numérique incorporant plus de décimales...), la variable en PL/SQL hérite d’emblée de ces modifications. Ce type a aussi le mérite de simplifier l’écriture de vos programmes.
On peut récupèrer dans un enregistrement l’ensemble des colonnes.
L’ouverture : PL/SQL permet d’utiliser des procédures externes (EXTERNAL PROCEDURE), c’est- à-dire un programme écrit en L3G, généralement le langage C. Les applications cibles sont très spécifiques et se rapprochent souvent des applications temps réel, scientifiques ou de traitement d’images.
L’appel de cette procédure externe peut s’effectuer à partir d’un bloc PL/SQL. C’est une possibilité très puissante : vous avez la possibilité de déclencher depuis la base de données des traitements extérieurs à la base.
Un accès aux données relationnelles-objet : Oracle est une base relationnelle qui offre des possibilités de stockage d’objets. PL/SQL propose des syntaxes permettant de manipuler des objets.
Le traitement des erreurs : Avec PL/SQL, il est facile d’identifier et de traiter les erreurs qui peuvent survenir dans vos programmes, car elles déclenchent des exceptions. L’erreur est alors transmise à la partie EXCEPTION de votre bloc PL/SQL pour y être traitée.
La plupart des exceptions sont définies en standard : par exemple, l’exception NO_DATA_FOUND survient lorsqu’un ordre SQL ne retourne aucune donnée. Outre celles-ci, vous pouvez ajouter vos propres exceptions, ce qui confère une grande souplesse d’utilisation.
DECLARE
excep_commission EXCEPTION ; DECLARE
IF commssion > salaire THEN
RAISE excep_commission ; -- branche sur l’exception ELSE
END IF ; EXCEPTION
WHEN excep_commission THEN -- traitement de l’exception BEGIN
... traitement END;
WHEN NO_DATA_FOUND THEN-- branchement automatique
Architecture de PL/SQL : Le PL/SQL est un langage de programmation destiné à être exécuté. Ce rôle revient au « moteur » PL/SQL qui n’est pas un produit séparé. Il est embarqué dans le cœur de la base de données ou dans certains outils de développement (exclusivement ceux d’Oracle). Un bloc PL/SQL peut être traité dans un outil de développement Oracle (SQL*Plus, Oracle Forms, Oracle Reports). Dans ce cas, seules les instructions conditionnelles sont traitées par le moteur PL/SQL embarqué dans l’outil de développement. Les ordres SQL incorporés dans les blocs PL/SQL sont toujours traités par la base de
Pour les blocs PL/SQL intégralement transmis à la base de données, la partie relative au traitement des instructions conditionnelles est effectuée par le moteur PL/SQL de la base ;
le traitement des ordres SQL incombe au moteur d’exécution de la base.
Fonctionnement de PL/SQL : Le SQL et le PL/SQL comportent chacun un « moteur d’exécution » associé, respective-ment le SQL STATEMENT EXECUTOR et le PROCEDURAL STATEMENT EXECUTOR. Le premier moteur se situe toujours dans la base de données ; quant au second, il peut se trouver avec le noyau Oracle ou avec l’outil de développement, uniquement pour les outils appartenant à la famille Oracle Developer.
Vous pouvez créer du code PL/SQL à partir de l’outil SQL*Plus (ou d’autres outils du marché) pour réaliser des procédures, fonctions, triggers, packages stockés dans votre base Oracle , et exécuter ces codes PL/SQL à partir de programmes réalisés avec presque tous les outils présents sur le marché. La différence de fonctionnement entre
le SQL STATEMENT EXECUTOR
et le PROCEDURAL STATEMENT EXECUTOR
tient à ce que le moteur SQL interprète les ordres SQL un par un, alors que le moteur PL/SQL interprète des blocs de commandes.
Si le moteur PL/SQL est incorporé aux outils Developer (Oracle Forms, Oracle Report),
seule la partie procédurale du bloc PL/SQL est exécutée dans l’outil. Les ordres SQL sont transmis à la base de données.
Si le bloc PL/SQL est directement transmis à la base de données, le traitement procédural
ainsi que les ordres SQL sont traités à l’intérieur de la base.
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 dernier peut contenir plusieurs « sous-blocs ». Les déclarations définies dans un bloc prennent fin en même temps que le bloc.
DECLARE
-- zone de déclaration de variables, constantes, -- exceptions, curseurs
BEGIN
-- traitements ...
-- instructions SQL et PL/SQL EXCEPTION
-- traitement des erreurs rencontrées
Remarque :
Vous pouvez placer des « sous-blocs » uniquement dans les sections BEGIN et EXCEPTION, pas dans la partie DECLARE.
DECLARE
-- zone de déclaration de variables BEGIN
-- bloc A
-- traitements ...
BEGIN -- bloc B
-- traitements bloc B END; -- fin du bloc B
-- autres traitements du bloc A EXCEPTION
-- traitement des erreurs rencontrées BEGIN -- bloc C
-- traitements bloc C END; -- fin du bloc C
Pour plus de lisibilité dans vos programmes, vous pouvez nommer les blocs afin d’en distinguer les différentes clauses BEGIN et END.
DECLARE
-- zone de déclaration de variables BEGIN BLOC_A -- bloc A
-- traitements ...
BEGIN BLOC_B-- bloc B -- traitements bloc B
END BLOC_B; -- fin du bloc B -- autres traitements du bloc A EXCEPTION
-- traitement des erreurs rencontrées BEGIN BLOC_C-- bloc C
-- traitements bloc C
END BLOC_C;-- fin du bloc C
Remarques
• Les zones DECLARE et EXCEPTION sont facultatives.
• Chaque instruction, de n’importe quelle section, se termine par un « ; ».
• Il est possible d’insérer des commentaires : -- commentaire sur une ligne
ou
/* commentaire sur plusieurs lignes
Exécution d’un programme PL/SQL avec SQL*Plus et iSQL*Plus :
Pour exécuter un programme PL/SQL, l’outil le plus simple livré par Oracle est SQL*Plus. Pour exécuter un bloc PL/SQL à partir de SQL*Plus, il convient de saisir l’intégralité du bloc, puis d’en lancer l’exécution par le signe « / », suivi d’un retour chariot.
DECLARE ...
BEGIN
-- traitements ...
EXCEPTION
-- traitement des erreurs rencontrées END;
/
Par exemple, sous SQL*Plus : SQL>
2 declare
3 ch varchar2(30);
4 begin
5 ch := 'pl/sql';
6 end;
/
Les variables PL/SQL : PL/SQL permet de déclarer des variables et des constantes, puis de les utiliser dans des ordres SQL ou des traitements. Seul impératif président à l’utilisation d’une variable : elle doit d’abord être déclarée dans la zone DECLARE.
La déclaration de variables PL/SQL : Les variables PL/SQL doivent appartenir à un type précis, qui correspond à ceux du langage SQL.
v_texte VARCHAR2(30);
v_vrai_faux BOOLEAN;
v_date_embauche DATE ;
Toutes les déclarations de variables doivent s’effectuer dans la zone DECLARE de votre bloc PL/SQL.
Les différents types de variables en PL/SQL :
Les types de variables les plus largement utilisés en PL/SQL sont les suivants :
NUMBER;-- longueur maxi 38 NUMBER(7,2);
CHAR;-- longueur maxi 2 000 CHAR(20);
VARCHAR2;-- longueur maxi 4 000 VARCHAR2(30);
Si le texte d’une variable de type CHAR n’atteint pas la totalité de la taille de la variable, il est automatiquement
« comblé » par des « blancs ». Au contraire, une variable
v_date DATE;-- pas de précision
v_date := ‘01-JAN-99’;-- format par défaut JJ- MON-YY
BOOLEAN;-- valeurs TRUE, FALSE, NULL v_test BOOLEAN := ‘TRUE’;
LONG_RAW;-- longueur maxi 32760 bytes en PL/SQL
ROWID;-- identifiant unique d’une colonne de table
BFILE;-- fichiers binaires extérieurs à la base
Variable faisant référence à la colonne d’une table
Cette façon de nommer les variables permet de récupérer automatiquement le type de la donnée tel qu’il est défini dans le dictionnaire de la base.
nom_var nom_table.nom_colonne%TYPE;
Ex :
Toute modification de la structure de la base de données (taille des colonnes de vos tables, de leur type...) sera alors sans effet sur les
programmes PL/SQL.
Variables faisant référence à la ligne d’une table Il est possible de déclarer un enregistrement, c’est-à- dire une ligne d’une table.
nom_enrg nom_de_ma_table%ROWTYPE;
Chaque variable de la structure de l’enregistrement comporte le même nom et le même type que la colonne associée.
DECLARE
enreg EMPLOYE%ROWTYPE;
...
BEGIN
IF enreg.nom = ‘EMP1’ THEN ...
...
...
IF enreg.noemp = ‘123456’ THEN...
...
Les types de variables définis par l’utilisateur Vous pouvez définir vos propres types de données en PL/SQL : l’ordre SUBTYPE
permet de les créer, même s’ils sont rarement utilisés.
DECLARE
SUBTYPE chdcar IS varchar2(30);
Ch 1 chdcar;
Affectation
Il existe deux façons d’affecter des valeurs à des variables.
:= La variable doit être placée à gauche de l’opérateur et la valeur à droite. Les fonctions et opérations du langage SQL sont applicables.
Effectuer un SELECT de valeurs en provenance de la base de données.
texte1 :='pl/sql';
texte2 := UPPER(‘pl/sql’);
test := TRUE ;
date_embauche:=TO_DATE(‘O1/01/2003’,’DD/MN/YYYY’) ; pi CONSTANT REAL := 3.14116 ;
Varaible1 … Variable2 ...
SELECT colonne1, colonne2,....
INTO variable1, variable2,....
FROM table
[WHERE conditions]
La clause INTO est obligatoire et l’ordre SELECT doit rapporter une seule ligne, sinon une erreur est générée. Si l’ordre SQL retourne plusieurs lignes, on utilisera obligatoirement un curseur (traité plus loin).
DECLARE
id_emp employe.noemp%TYPE := ‘1000’;
nom_emp employe.nom%TYPE ;
salaire_emp employe.salaire%TYPE ; BEGIN
SELECT nom, salaire
INTO v_nom_employe, v_salaire_employe FROM employe
WHERE empno := d_emp ; ...
– afficher/traiter id_emp / nom_emp / salaire_emp
Les structures de contrôle
C’est l’une des plus importantes caractéristiques de PL/SQL. Ces structures permettent de contrôler l’exécution des ordres SQL et de traiter de façon procédurale les données. Ces clauses trouvent toute leur utilité dans l’exécution des curseurs en permettant le traitement ligne à ligne des enregistrements retournés par un curseur. Les principales structures
sont les suivantes :
• IF-THEN-ELSE ;
• FOR-LOOP ;
• WHILE-LOOP ;
IF-THEN-ELSE :Cette syntaxe permet d’exécuter des instructions en fonction du résultat d’une condition. La syntaxe générale se présente comme suit :
BEGIN ...
IF condition1 THEN traitement1 ;
ELSIF condition2 THEN traitement2 ; ELSE traitement3 ;
END IF;
...
Les opérateurs utilisés dans les conditions sont les mêmes que dans les ordres SQL :
=, <, >, !=, >=, <=,
IS NULL, IS NOT NULL, BETWEEN, LIKE, AND, OR, etc...
RQ :
Seules les clauses IF, THEN, END IF sont
obligatoires.
Ex :
Augmenter le salaire de l employé emp1 de :
10% si son salaire est inferieur à 10000
5% sin son salaire est entre 10000 et 30000
2.5% sin salaire est supérieur à 30000
DECLARE
Sal NUMBER(7);-- variable locale BEGIN
SELECT salaire INTO sal FROM emp WHERE nom = ‘emp1’
FOR UPDATE OF sal;
IF sal <= 10000 THEN
UPDATE emp SET sal = sal*1,1 WHERE ename = ‘emp1’;
ELSIF sal BETWEEN (1000 and 5000) THEN UPDATE emp SET sal = sal*1,05
WHERE ename = ‘emp1’;
ELSE UPDATE emp SET sal = sal*1,025 WHERE ename = ‘emp1’;
END IF;
La boucle LOOP : PL/SQL permet d’effectuer des traitements répétitifs grâce à la clause LOOP, qui trouve toute son utilité dans le traitement des curseurs : les enregistrements retournés par un curseur peuvent en effet être traités ligne par ligne.
BEGIN ...
LOOP [<<nom_boucle>>]
instructions ;
END LOOP [nom_boucle];
...
Telle qu’elle est écrite, cette boucle s’exécute indéfiniment. C’est l’instruction EXIT qui stoppe l’exécution entre le LOOP et le END LOOP.
EXIT [nom_boucle] [WHEN condition]
Ex : Ecrire un programmequi permet de
calculer les puissances de 2 inférieures à 100 :
DECLARE
P2 NUMBER := 2;
BEGIN LOOP
INSERT INTO table_resultat VALUES (p2) ; p2 := p2 * p2;
EXIT WHEN p2>= 100 ; END LOOP ;
END;
La boucle FOR-LOOP simplifie l’écriture des boucles LOOP et garantit la prise en compte de la condition de sortie d’une boucle LOOP seule:
BEGIN ...
FOR variable_indice IN valeur1 .. valeur2 LOOP
instructions ; END LOOP ; ...
● Avec cette syntaxe, il est inutile de déclarer la variable variable_indice, car ce processus
est automatique.
● valeur1 et valeur2 sont des expressions, des variables ou des constantes.
● Le pas d’incrément de variable_indice est de 1, compris entre valeur1 et valeur2.
EX :
Afficher la table de 5
DECLARE
cte CONSTANT := 5;
res NUMBER;
BEGIN
FOR i IN 1 .. 9 LOOP
res := cte * i ;
-- stockage du résultat dans une colonne VARCHAR2 INSERT INTO table_resultat
VALUES(cte||’*’||i||’=‘||res);
END LOOP ; END;
La boucle WHILE-LOOP s’exécute tant que la condition de la clause WHILE est vérifiée.
BEGIN ...
WHILE condition LOOP
instructions ; END LOOP ; ...
Les opérateurs utilisés dans la condition sont les mêmes que dans les ordres SQL :
=, <, >, !=, >=, <=,
IS NULL, IS NOT NULL, BETWEEN, LIKE, AND, OR, etc...
EX :
Afficher la table de 5 avec WHILE-LOOP
DECLARE
cte CONSTANT := 5;
res NUMBER;
i NUMBER := 1;
BEGIN
WHILE i <= 9 LOOP
res:= cte * i ;
-- stockage du résultat dans une colonne VARCHAR2 INSERT INTO table_resultat VALUES (cte||’*’||i||’=‘||res);
i := i + 1 ; END LOOP ; END;