Introduction à PLSQL

pour plus d'infos voir les excellents polys disponibles sur le site du labo Oracle de SUPINFO

L'intro de l'intro

PL/SQL est un langage qui intègre SQL et permet de programmer de manière procédurale. Il est spécifique à Oracle. Pour SQL Server il existe par exemple un équivallent : TRANSAC SQL

Globalement, avec PL/SQL on aura à notre disposition un vrai langage de programmation moins intuitif mais aussi plus puissant que le SQL. Les 2 langages sont éminemment complémentaires.

Les principaux avantages / inconvénients sont les suivants :
- ne dispense pas de connaître le SQL,
- permet le traitement par bloc de SQL et donc optimise le trafic réseau,
- l'utilisation de variable de stockage et de type simple et strucuré dynamique (%TYPE, %ROWTYPE, etc)
- des traitements plus complexes, notamment pour la gestion des cas particuliers et des erreurs (traitement des exceptions),
- l'utilisation de librairies standards prédéfinies (supplied PLSQL packages, comme les RDBMS_xxx),
- un paramétrage et la création d'ordres SQL dynamiques.

Le PL/SQL peut être utilisé sous 3 formes :

 ordres SQL supportés dans PL/SQL

Les instructions du langage de manipulation de données (LMD) et certaines instructions de gestion de transaction, à savoir :
- INSERT, UPDATE, DELETE, SELECT,
- COMMIT, ROLLBACK, SAVEPOINT,
- LOCK TABLE,
- SET TRANSACTION READ ONLY.
Avec les versions antérieures à la 9i, Les ordres du LDD ne sont pas supportés par défaut il faut utiliser un package spécial comme dans le script suivant.

Mots réservés PL/SQL

La liste des mots réservés PL/SQL est disponible ici, au format PDF.

Blocs et sections PL/SQL

Les blocs de code s'appellent également des blocs anonymes.
Ils commenceront simplement par un 'BEGIN' ou un 'DECLARE'.
Ils sont composés de 1 à 3 sections :

Type de section obligatoire ? Mots clés
section déclarative non DECLARE...
section exécutable oui BEGIN ...END;
section de traitement des exceptions non EXCEPTION

la section 'exeption' quand elle est présente est incluse dans la section et NON PAS à la suite de celle ci.

(DD is proud to announce...)le plus petit bloc PL/SQL au monde:

SQL> BEGIN
NULL;
END;
.
/
Procedure PL/SQL terminee avec succes.

le bloc ne peut pas être vide et doit contenir au moins une instruction...le '.' sous SQL*PLus sert a arrêter la saisie du code PL/SQL et le '/' comme toujours à executer le contenu du buffer de commande courant.

avec une déclaration de variable un (tout petit) bloc PL/SQL ca donne ça :

SQL> DECLARE x INTEGER;
BEGIN
X := 1;
END;
.
Procedure PL/SQL terminee avec succes.

un bloc avec des exceptions a donc la structure suivante :

DECLARE -- mes déclarations de variables...
BEGIN -- début de la section executable
-- mes ordres SQL et PLSQL
EXCEPTION
-- mon traitement des exceptions
END; -- la fin du bloc executable

 

procédure PL/SQL

Une procédure est simplement un programme PL/SQL nommé, compilé et stocké dans la base. On trouvera ci après le code de la plus petite procédure PL/SQL au monde ;-)

SQL> CREATE OR REPLACE PROCEDURE proc_mini
IS
BEGIN
NULL;
END;
/
Procedure cree.

Pour être un peu plus précis, ce code est une commande SQL, qui crée la procédure PL/SQL, et donc compile et stocke dans la base le bloc PL/SQL compris entre le BEGIN et le END, en le référencant par ‘proc_mini’.

Et pour exécuter cette procédure de manière autonome :
SQL> EXECUTE proc_mini
Procedure executee avec succes.

Voici le célèbre hello.pl (libre et originale adapdation du hello.c) ici sous forme de procédure stockée.

Un exemple un petit peu moins minimaliste, de procédure avec paramètre est donné ci-après :
PROCEDURE cree_client (p_nom VARCHAR2, p_ville VARCHAR2) IS
BEGIN
INSERT INTO clients (no_cli, nom_cli, ville_cli)
VALUES (seq_noclient.NEXTVAL, p_nom, p_ville);
COMMIT ;
END;

fonctions PL/SQL

Une fonction est une procédure retournant une valeur.

SQL> CREATE OR REPLACE FUNCTION solde (no INTEGER)
RETURN REAL IS le_solde REAL;
BEGIN
SELECT solde INTO le_solde FROM clients
WHERE no_cli = no;
RETURN le_solde;
END;
/

On peut par exemple appeler cette fonction et utiliser son résultat au sein d’un ordre SQL :

SQL> SELECT solde(1000) FROM dual ;
Solde(1000)
-----------
12024,50

l'appel 'bête' de l'exécution d'une fonction comme si c'étatit une procédure (ouh la la !) ne fonctionne évidemment pas! mais on est souvent tenté de le faire quand même.

Soit la fonction stockée mdp() qui accepte un paramètre numérique. SI on l'appelle sans prendre garde au fait que c'est une fonction, on obtient :

SQL> execute mdp(2);
BEGIN mdp(2); END;
*
ERREUR a la ligne 1 :
ORA-06550: line 1, column 7:
PLS-00221: 'MDP' is not a procedure or is undefined
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

package PL/SQL

Un package est un module de programmes incluant procédures et / ou fonctions fonctionnellement dépendantes.
Un package est composé de 2 parties :
- la spécification (introduite par ‘CREATE PACKAGE’) liste les entêtes de procédures et fonctions contenues dans le package,
- le corps du package (introduit par ‘CREATE PACKAGE BODY’) qui contient le code effectif des procédures et fonctions déclarées précédemment.
exemple
SQL> CREATE PACKAGE clients AS -- spécifications du package
PROCEDURE insere_client (no INTEGER, nom VARCHAR2, ...);
PROCEDURE supprime_client (no INTEGER);
...
END;
/

SQL> CREATE PACKAGE BODY clients AS -- le corps du package
PROCEDURE insere_client (no INTEGER, nom VARCHAR2, ...) IS
BEGIN
...
INSERT INTO clients VALUES (no, nom, ...);
END;

PROCEDURE supprime_client (no INTEGER) IS
BEGIN
DELETE FROM clients WHERE no_cli = no;
END;
...
END; -- du package
/

trigger

Un trigger est un morceau de code PL/SQL, stocké dans la base, déclenché lors de l’occurrence d’un événement particulier. Ils permettent notamment de synchroniser des opérations entre plusieurs tables.
Note
On est parfois tenté de créer des triggers pour implémenter certaines règles de gestion. La plupart du temps les contraintes remplissent plus efficacement ce rôle.

La plupart du temps les triggers sont déclenchés par la modification du contenu d’une table. La liste des événements déclencheurs apparaît ci-après :

Type d’ordre ordre déclencheur
LMD DELETE, INSERT, UPDATE
LDD CREATE, ALTER, DROP
Base de donnée SERVERERROR, LOGON, LOGOFF, STARTUP, SHUTDOWN

Les ordres du LDD et de la gestion de transaction (CREATE, ALTER, DROP, COMMIT, SAVEPOINT, sont interdits pour les triggers autres que base de données (triggers système).

exemple de trigger
-- trigger déclenché lors d’une insertion
-- ou d’une modification de la table client
SQL> CREATE OR REPLACE TRIGGER aff_discount
BEFORE INSERT OR UPDATE ON clients
FOR EACH ROW
WHEN (new.no_cli > 0)
DECLARE
    evol_discount number;
BEGIN
    evol_discount := :new.discount  - :old.discount;
    DBMS_OUTPUT.PUT_LINE('  evolution : ' || evol_discount);
END;
/
-- FOR EACH ROW signale qu’une modification de 4 lignes
-- par un seul UPDATE déclenche 4 fois le trigger.
-- Si on ne souhaite qu’un seul déclenchement ,
-- on omet simplement la clause FOR EACH ROW

 

(c) 2002- 2005 Didier Deléglise
(c) 2002- 2006 Didier Deléglise


modifié
le 20/11/2006

Ecrire a DD
ecris
moi


les forums techniques Oracle

mon BLOG Oracle,
en Francais
connaitre DD
l'autre vie
de DD

mon CV

trucs
et astuces

JOBs Oracle
du jour
Homepage "Tout sur Oracle"
Mon site :
Tout sur Oracle (et le web)
Copyright (C) 2002
Utilisation de ces documents