Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
PL/SQL
PL/SQL = PROCEDURAL LANGUAGE/SQL
SQL est un langage non procédural
Les traitements complexes sont parfois difficiles à écrire si on
Marc Plantevit ne peut utiliser des variables et les structures de
programmation comme les boucles et les alternatives
On ressent vite le besoin d’un langage procédural pour lier
plusieurs requêtes SQL avec des variables et dans les
structures de programmation habituelles
marc.plantevit@liris.cnrs.fr
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 2
Extension de SQL : des requêtes SQL cohabitent avec les PL/SQL peut être utilisé pour l’écriture des procédures
stockées et des triggers.
structures de contrôle habituelles de la programmation
Oracle accepte aussi le langage Java.
structurée (blocs, alternatives, boucles).
La syntaxe ressemble au langage Ada ou Pascal. Il convient aussi pour écrire des fonctions utilisateurs qui
peuvent être utilisées dans les requêtes SQL (en plus des
Un programme est constitué de procédures et de fonctions. fonctions prédéfinies).
Des variables permettent l’échange d’information entre les Il est aussi utilisé dans des outils Oracle
requêtes SQL et le reste du programme Ex : Forms et Report.
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 3 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 4
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 5 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 7
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 8 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 9
Plusieurs façons d’affecter une valeur à une variable
Déclaration et initialisation
Nom variable type variable := valeur ; Opérateur d’affectation n :=.
Initialisation Directive INTO de la requête SELECT.
Nom variable := valeur ;
Déclarations multiples interdites. Exemple
Exemples : dateNaissance :=
age integer ; to date(’10/10/2004’,’DD/MM/YYYY’) ;
nom varchar(30) ; SELECT nom INTO v nom
dateNaissance date ;
FROM emp
ok boolean := true ;
WHERE matr = 509 ;
Pour éviter les conflits de nommage, préfixer les variables
PL/SQL par v
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 10 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 11
VARCHAR2
Longueur maximale : 32767 octets ;
SELECT expr1,expr2, . . . INTO var1, var2, . . . Syntaxe : Nom variable VARCHAR2(30) ;
Met des valeurs de la BD dans une ou plusieurs variables var1, Exemples :
var2, . . . name VARCHAR2(30) ;
Le select ne doit retourner qu’une seule ligne name VARCHAR2(30) := ’toto’ ;
Avec Oracle il n’est pas possible d’inclure un select sans
into dans une procédure.
NUMBER(long,dec)
Pour retourner plusieurs lignes, voir la suite du cours sur les Long : longueur maximale ;
curseurs. Dec : longueur de la partie décimale ;
Exemples :
num telnumber(10) ;
toto number(5,2)=142.12 ;
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 12 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 13
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 14 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 15
IF-THEN
DECLARE IF v date > ’01-JAN-08’ THEN
-- Déclaration v salaire := v salaire * 1.15 ;
v employe emp%ROWTYPE ; END IF ;
v nom emp.nom.%TYPE ;
BEGIN IF-THEN-ELSE
SELECT * INTO v employe FROM emp WHERE matr = 900 ; IF v date > ’01-JAN-08’ THEN
v nom := v employe.nom ; v salaire := v salaire * 1.15 ;
v employe.dept := 20 ; ELSE
... v salaire := v salaire * 1.05 ;
/* On insère un tuple dans la base*/ END IF ;
INSERT into emp VALUES v employe ;
IF-THEN-ELSIF
END ;
Vérifiez à bien retourner un seul tuple avec la requête SELECT ... IF v nom = ’PARKER’ THEN
INTO ... v salaire := v salaire * 1.15 ;
ELSIF v nom = ‘SMITH’ THEN
v salaire := v salaire * 1.05 ;
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 16 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 18
ENDIF ;
CASE Les Boucles
CASE
WHEN
sélecteur
expression1 THEN résultat1 Le CASE renvoie une LOOP
WHEN expression2 THEN résultat2 valeur qui vaut résultat1 instructions exécutables ;
ELSE résultat3 ou résultat2 ou . . . Ce EXIT[WHEN condition] ;
END ; n’est pas une instruction. instructions exécutables ;
END LOOP ;
Exemple
val := CASE city
Obligation d’utiliser la commande EXIT pour éviter une
boucle infinie, facultativement quand une condition est
WHEN ’TORONTO’ THEN ’RAPTORS’ vraie.
WHEN ’LOS ANGELES’ THEN ‘LAKERS’ WHILE condition LOOP
WHEN ’SAN ANTONIO’ THEN ’SPURS’ instructions exécutables ;
ELSE ’NO TEAM’ END LOOP ;
END ; -- Tant que la condition est vraie ...
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 19 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 20
FOR Affichage
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 21 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 22
set serveroutput on
DECLARE DECLARE
i number(2) ; compteur number(3) ;
BEGIN i number(3) ;
FOR i IN 1..5 LOOP BEGIN
dbms output.put line(’Nombre : ’ || i) ; select count(*) into compteur from EtudiantLIF10 ;
END LOOP ; FOR i IN 1..compteur LOOP
END ; dbms output.put line(’Nombre : L3IF ’ || i ) ;
/ END LOOP ;
Si ’/’ seul sur une ligne : fin d’une définition (déclenche END ;
l’évaluation).
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 23 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 24
Tous les curseurs ont des attributs que l’utilisateur peut utiliser.
%ROWCOUNT :
Nombre de lignes traitées par le curseur
Toutes les requêtes SQL sont associées à un curseur.
Ce curseur représente la zone mémoire utilisée pour parser %FOUND
(analyser) et exécuter la requête.
Vrai si au moins une ligne a été traitée par la requête ou le dernier
Le curseur peut être implicite(pas déclaré par l’utilisateur) ou fetch.
explicite/
Les curseurs explicites servent à retourner plusieurs lignes avec %NOTFOUND
un select. Vrai si aucune ligne n’a été traitée par la requête ou le dernier fetch
%ISOPEN
Vrai si le curseur est ouvert (utile seulement pour les curseurs
explicites)
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 26 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 27
Les curseurs implicites Les curseurs explicites
Les curseurs implicites sont tous nommés SQL Pour traiter les select qui renvoient plusieurs lignes.
Ils doivent être déclarés.
Exemple Le code doit les utiliser explicitement avec les ordres OPEN,
DECLARE FETCH et CLOSE
nb lignes integer ; OPEN moncurseur : ouvre le curseur.
BEGIN FETCH moncurseur : avance le curseur à la ligne suivante.
OPEN moncurseur : referme le curseur.
delete from emp where dept = 10 ;
nb lignes := SQL%ROWCOUNT ; Le plus souvent on les utilise dans une boucle dont on sort
... quand l’attribut NOTFOUND du curseur est vrai.
END ; On les utilise aussi dans une boucle FOR qui permet une
utilisation implicite des instructions OPEN, FETCH et
CLOSE.
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 28 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 29
BEGIN
open salaires ;
LOOP
On peut déclarer un type
row associé à un curseur :
DECLARE
FETCH salaires into salaire ;
CURSOR c IS SELECT matr, nom, sal FROM emp ;
EXIT when salaires%notfound ;
employe c%ROWTYPE ;
IF salaire is not null THEN
total := total + salaire ; Ne pas oublier de BEGIN
open c ;
DBMS OUTPUT.put line(total) ; fermer le curseur.
fetch c into employe ;
END IF ;
IF employe.sal IS NOT NULL THEN
END LOOP ;
...
CLOSE salaires ;
END ;
DBMS OUTPUT.put line(total) ;
END ;
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 30 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 31
DECLARE
nom varchar2(30) ;
CURSOR c nom clients IS SELECT nom,adresse FROM
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 32 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 33
DECLARE
-- Déclaration du paramètre du curseur.
CURSOR c(p dept integer) IS select dept, nome from
emp where dept = p dept ;
Un curseur paramétré peut servir plusieurs fois avec des
BEGIN
valeurs des paramètres différentes.
-- Instantiation du paramètre avec le dept 10.
On doit fermer le curseur entre chaque utilisation de FOR employe in c(10) LOOP
paramètres différents (sauf si on utilise for qui ferme dbms output.put line(employe.nome) ;
automatiquement le curseur). END LOOP ;
-- Instantiation du paramètre avec le dept 20.
FOR employe in c(20) LOOP
dbms output.put line(employe.nome) ;
END LOOP ;
END ;
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 34 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 35
Les Exceptions Exceptions Prédéfinies
NO DATA FOUND
Quand Select into ne retourne aucune ligne.
Une exception est une erreur qui survient durant une
exécution.
TOO MANY ROWS
2 types d’exception :
Quand Select into retourne plusieurs lignes.
prédéfinie par Oracle,
définie par le programmeur.
VALUE ERROR
Saisir une exception :
Erreur numérique.
Une exception ne provoque pas nécessairement l’arrêt du
programme si elle est saisie par un bloc (dans la partie
EXCEPTION ).
ZERO DIVIDE
Une exception non saisie remonte dans la procédure appelante Division par zéro.
(où elle peut être saisie).
OTHERS
Toutes erreurs non interceptées.
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 37 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 38
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 42 SET SERVEROUTPUT
Le Langage PL/SQL ON ;Les curseurs
Commandes Les exceptions Procédures et fonctions Triggers 43
Exécution :
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 46 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 47
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 48 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 50
Utilisation de new et old. Créer la table LOG CLIENTS avec la même structure que
CLIENTS.
Si nous ajoutons un client dont le nom est toto alors nous Ajouter 3 colonnes USERNAME, DATEMODIF,
TYPEMODIF.
récupérons ce nom grâce à la variable :new.nom.
Prédicats Conditionnels
On peut préciser les colonnes soumises aux opérations le corps d’un trigger. Ainsi, les commandes ROLLBACK, COMMIT,
..., ne doivent pas être utilisées dans le corps d’un trigger.
déclenchantes :
CREATE TRIGGER ...
... UPDATE OF sal, commission ON EMP ...
BEGIN
...
IF UPDATING(’SAL’) THEN
...
END IF
END ;
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 53 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 54
Tables Mutantes et Tables Contraignantes Exemple d’erreur
Une table mutante est une table en cours de modification par CREATE OR REPLACE TRIGGER emp count
une opération déclenchante (UPDATE, DELETE, AFTER DELETE ON emp
INSERTION) ou l’effet de DELETE CASCADE provenant de FOR EACH ROW
cette opération. DECLARE
Une table contraignante est une table qu’une opération n INTEGER ;
déclenchante doit lire, soit directement via une commande BEGIN
SQL (UPDATE SET ... WHERE) ou indirectement pour une SELECT COUNT(*) INTO n FROM emp ;
contrainte d’intégrité référentielle. DBMS OUTPUT.PUT LINE(’On a ’|| n || ’employés dans la
Les commandes SQL dans le corps d’un trigger ne peuvent
base’) ;
pas :
Lire (par une requête) ou modifier un table mutante d’une
opération déclenchante. DELETE FROM emp WHERE empno = 7499 ;
Changer des valuers sur les colonnes de clés (PRIMARY, On a l’erreur suivante :
FOREIGN, UNIQUE) d’une table contraignante. ORA-04091 : table SCOTT.EMP is mutating,
Ces restrictions permettent d’éviter la consultation d’une table trigger/function may not see it.
dans un état transitoire et donc incohérent.
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 55 Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 56
Le Langage PL/SQL Commandes Les curseurs Les exceptions Procédures et fonctions Triggers 57