Вы находитесь на странице: 1из 100

Support dutilisation

PL/SQL 2.x

Jean-Marc Petit

Farouk Toumani

Plan du support
 Introduction gnrale PL/SQL
Motivations, Intrts

 Blocs PL/SQL
Les types de donnes PL/SQL
Les types scalaires
Les types composs






Les
Les
Les
Les

structures de contrle
curseurs
exceptions
sous-programmes

Les procdures
Les fonctions
Les packages

 Les triggers
 Conclusion
2

Introduction gnrale

Pourquoi lier SQL un LP ?


 Permet de relier la technologie des BDs et des langages
de programmations (LP)
 Etend le langage standard SQL
 Combine
la puissance de manipulation des donnes offerte par SQL
(insert, delete, SFW, )
avec la puissance des langages de programmation
(boucle, branchement, )

PL quoi ?
PL/SQL !
 Pour les dveloppeurs de programmes accdant une
base de donnes ORACLE
 PL/SQL est un langage de programmation
 PL/SQL permet d'augmenter SQL par des capacits
procdurales.
 Code PL/SQL accessible de plusieurs environnements:
SQL*Plus, SQL*Forms, SQL*Reports, ...

Relation entre SQL et PL/SQL


 PL/SQL = la plupart des dclarations SQL combines
avec les principales instructions des LP
 Instructions :
Structure de contrle :
if then else, exit, goto
Structure de rptition:
while loop, for loop
Affectation :
x :=y+z
Squencement :
;

A la diffrence de SQL, PL/SQL permet de grouper un


ensemble logique de dclarations afin de les envoyer en
un seul bloc au SGBDR.

Avantages de PL/SQL
Capacit procdurale : L4G + LP
Amlioration des performances : diminution du
trafic dans un environnement rseau
(diminution des communications)
Productivit amliore : PL/SQL est le mme
pour tous les environnements
Portabilit : indpendant des plate-formes, du
systme d'exploitation.
Intgration directe avec le SGBDR
7

Un exemple de bloc PL/SQL


DECLARE
nbre_en_stock NUMBER(5);
BEGIN
SELECT quantit INTO nbre_en _stock FROM
table_des_inventaires
WHERE produit = RAQUETTE DE TENNIS';
- - tre sur qu'il y en a assez en stock
IF nbre_en_stock > 0 THEN
UPDATE table_des_inventaires SET quantit = quantit - 1
WHERE produit = RAQUETTE DE TENNIS';
INSERT INTO enregistrement_achats
VALUES (RAQUETTE DE TENNIS ACHETEE.', SYSDATE);
ELSE
INSERT INTO enregistrement_achats
VALUES ( PLUS DE RAQUETTE DE TENNIS.', SYSDATE);
END IF;
COMMIT;
END;
8

Le SQL admis
Dclaration des manipulations de donnes
INSERT, SELECT, UPDATE, DELETE

Dclarations des transactions :


COMMIT, ROLLBACK, SAVEPOINT

Diffrents types de fonctions SQL :


NUMERIC, CHARACTER, DATE, GROUP, DATA,

CONVERSION

Prdicats SQL
utiliss dans la clause WHERE (and, or, not) et
les oprateurs de comparaison between, in, is null,

like

Le SQL non admis (Version 7)


Les dclarations de dfinition de donnes
ALTER, CREATE, RENAME
Les dclarations de contrle des donnes
CONNECT, GRANT, REVOKE

10

Les capacits procdurales


d'ORACLE
PL/SQL est un langage de programmation
classique
PL/SQL permet de coder
les triggers
augmentent les capacits procdurales d'ORACLE

les procdures stockes, les packages

Limites :
Primitives d'E/S faibles,
tableaux limits
11

12

Blocs PL/SQL

Quelques trucs de syntaxe











- - : commentaire sur une ligne


/**/ : commentaire sur plusieurs lignes
idf1&idf2 : illgal
idf1-idf2 : illgal (pas de blanc non plus)
on/off : illgal
lastname=LastName=LASTNAME
lastname last_name
'string' 'String' 'STRING'

14

Notions de bloc PL/SQL


Le bloc est le concept de base de PL/SQL
Un bloc est anonyme
Structure d'un bloc :
DECLARE
[dclarations ]
BEGIN
Instructions PL/SQL
[EXCEPTION
traitement des exceptions]
END;

15

Types de donnes
Classique aux LPs :
Types scalaires :
tous les types de base usuels

Types composs :
tableaux et enregistrements

Non classique aux LPs


Curseurs : fait le lien entre une requte et un
programme

A partir de Oracle V8, possibilit de dfinir


des objets (pas trait dans ce support)
16

Types scalaires
 Types scalaires:
binary-integer: natural, positive;
number: decimal, float, integer ;
char: string, character;
varchar2 (prfrable varchar):
long, longraw, raw;
date;
boolean

 Conversion de types
Conversions explicites (exemple fonction to_date ..)
Conversions implicites faites par le compilateur ( viter)
17

Variables et constantes
 Les constantes
introduites par le mot rserv CONSTANT
Exemple :
Bonus CONSTANT NUMBER(3,2) := 0.12;

 Les variables
le type de donnes peut tre natif d'ORACLE (NUMBER,
CHAR, DATE ...) ou de PL/SQL (BOOLEAN, TABLE)
Exemple :
Taxe NUMBER (7,2);
ok BOOLEAN;

18

Affectation de variables
 Introduites par l'oprateur :=
Exemple :
taxe := prix * taux_taxe

 Introduites par le mot rserv INTO


Exemple :
SELECT salaire INTO variable
FROM Employs
WHERE nemp = 1232

19

Variables et constantes
 A partir des attributs des tables
 Dclarations
%TYPE : mot rserv pour accder un attribut
dune table
Exemple :
var_ename EMP.ENAME%TYPE;

%ROWTYPE : mot rserv pour rfrencer une


ligne dune table
Exemple :
var_emp EMP%ROWTYPE;
20

Suite
 %ROWTYPE : fournit un type record qui reprsente
une ligne d'une relation
DECLARE
emp_rec emp%ROWTYPE;
cursor c1 is select depno,dname,loc from dept;
dep_rec c1%ROWTYPE;

 Faire un alias: obligatoire quand les attributs d'un


curseur sont des expressions.
CURSOR c is SELECT sal + NVL(-,-) alias_name,

 "Rfrences avant" non permises


pour les variables/constantes mais possible pour les sousprogrammes.

 Dclarations multiples non autorises


i,j,k smallint; - - Illicite

21

Les principales dclarations


 Dclaration et assignation de valeur par dfaut
taxe REAL (2,1):= 18.6;
taxe REAL (2,1) DEFAULT 18.6;

 %type : fournit le type de donnes dune variable ou


dune constante ou dune colonne ( le plus utilis)
Indpendance des ventuels changements sur le schma de
relation
Portabilit augmente
Attention ce type dutilisation:
R (, a, ) avec une contrainte NOT NULL sur l'attribut a
DECLARE V.a R.a%TYPE;
BEGIN
V.a := NULL;
END;

22

Conventions syntaxiques
 Conventions de nommage
tre rigoureux, explicite, fidle !!!

 Politique de nommage au sein d'un groupe


facilite lutilisation de toutes les nouvelles fonctionnalits de
PL/SQL (package ).

 Exemple de ce quil ne faut pas faire :


DECLARE ename CHAR(10):=KING'
BEGIN
delete from emp where ename=ename;
END;

Puisque les noms d'attribut sont toujours prioritaires


=> suppression des tuples de la table emp

 Porte et visibilit des variables


comme pour les langages de programmation usuels

23

Exemples : structures des


blocs et rgles de porte
DECLARE
x
NUMBER := 0;
counter NUMBER := 0;
BEGIN
FOR i IN 1..4 LOOP
x := x + 1000;
counter := counter + 1;
INSERT INTO temp VALUES (x, counter, 'in OUTER loop');
/* start an inner block */
DECLARE
x NUMBER := 0;
-- this is a local version of x
BEGIN
FOR i IN 1..4 LOOP
x := x + 1;
-- this increments the local x
counter := counter + 1;
INSERT INTO temp VALUES (x, counter, 'inner loop');
END LOOP;
END;
END LOOP;
COMMIT;
END;

24

Expressions et comparaisons
Prcdence classique des oprateurs
Oprateurs logiques (table de vrit fournies)
Oprateurs de comparaisons
Manipulations des nulls :
comparaison avec un NULL donne NULL
(toujours)
NOT (quelque chose NULL) donne NULL
NULL quivaut FALSE dans une condition
boolenne
25

Expressions et comparaisons
(suite)
Fonctions prdfinies:
nvl, decode, (cf liste exhaustive)

Fonctions intgres
Fonctions sur les nombres (cos, sin, ...)
Fonctions sur les caractres
Fonctions de conversion
Autres
26

Types composs
Table
notion de tableau

Record
notion d'enregistrement
struct en C/C++
record en Pascal

=> classique aux LPs


Rappel :
possibilit de dfinir des objets partir de

Oracle V8

27

Types composs : table


 Ne pas confondre le constructeur de type TABLE et
un type Table
 Syntaxe:
TYPE type-name IS TABLE OF
{column-type | variable%type | table.column%type}
[NOT NULL]
INDEX BY BINARY-INTEGER;

 Le type admis dans une table est


OBGLIGATOIREMENT un type scalaire.
 Tableau de tableau et tableau de record non permis
28

Table (fin)
 Exemple avec une table de caractres et de noms :
DECLARE
TYPE tab1 IS TABLE OF CHAR(10) INDEX BY BINARY-INTEGER;
TYPE tab2 IS TABLE OF emp.ename%TYPE INDEX BY BINARY-INTEGER;

 Variable sur un type table : comme pour les types


scalaires
V_ tab tab1;

 Rfrencer un lment dune table (ou tableau) :


V_tab(3); - - troisime lment du tableau V_ tab
29

Types composs : record


 Ne pas confondre le constructeur de type RECORD et un
type Record
 Syntaxe:
TYPE type-name IS RECORD
( chp1
{type1 | variable%TYPE | table.column%TYPE |table%ROWTYPE}
[NOT NULL],
chp2 { } [NOT NULL],
);

 Exemple :
DECLARE
TYPE DeptRecTyp IS RECORD
(depno NUMBER(2) NOT NULL,
dname dept.dname%type,
loc dept.loc%type);

 Records imbriqus permis (record de record)

30

Record (fin)
 Une fois un type record dfini, on peut dclarer des
variables de ce type.
V_dept_rec DeptRecTyp;

 Rfrencer un record:
nom_record.nom_champ

 Exemple d'affectation:
DECLARE
TYPE DeptRecTyp IS RECORD
(deptno NUMBER(2), dname CHAR(14), loc CHAR(13));
dept_rec DeptRecTyp;
BEGIN
SELECT deptno, dname, loc into dept_rec
FROM dep
WHERE deptno=30;
END;

31

32

Les structures de contrle

Le contrle conditionnel
 IF condition
Cette clause vrifie si la condition est vraie (TRUE) ou pas

 THEN instructions
Dfinit la squence d'instruction excuter quand la
condition est vraie.

 ELSEIF condition
Si la condition dfinie aprs le IF est FALSE (ou NULL), le
ELSEIF permet de vrifier une autre condition

 ELSE
Dfinit la squence excuter quand aucune condition n'est
vrifie

34

Comparaisons logiques
 Sur les nombres : =, !=, <, >, <=, >=
 sur les charactres : =, !=, <, >, <=, >=
 sur les dates : =, !=, <, >, <=, >=
Notion de polymorphisme
=> classique aux LPs

35

Contrle des itrations


 Dclarations des boucles :
LOOP END LOOP
Boucle FOR
Boucle WHILE
Dclarations de sortie EXIT

 Dclarations des GOTO


positionnement d'un label par <<nom-du-label>> et
rfrence celui-ci avec un GOTO <<nom-du-label>>.

 Conseil : ne pas utiliser GOTO !!!


36

Les Traitements Rptitifs (1)


PL/SQL dispose de 4 types de boucles:
1 La boucle de base LOOP END LOOP
Permet de rpter une squence d'instructions place
entre les deux mots cls LOOP et END LOOP.

2 La boucle FOR LOOP END LOOP


Cette boucle permet de spcifier un intervalle
d'entiers, la boucle LOOP END LOOP est rpte
pour chaque entier appartenant cet intervalle.
=> vite des changements de contexte entre SQL et
PL/SQL (gain de temps)
37

Les Traitements Rptitifs (2)


3 La boucle WHILE
Dans cette boucle une condition est associe la
squence d'instructions rpter.
L'excution de la boucle s'arrte quand cette
condition n'est plus vrifie

4 La boucle CURSOR FOR


C'est la boucle associe au curseur

Remarque: lordre EXIT permet de sortir d'une


boucle immdiatement

38

/*
** This block finds the first employee who has a salary over $4000
** and is higher in the chain of command than employee 7902.
**
** Copyright (c) 1989,1992 Oracle Corporation
*/
DECLARE
salary
emp.sal%TYPE;
mgr_num
emp.mgr%TYPE;
last_name
emp.ename%TYPE;
starting_empno CONSTANT NUMBER(4) := 7902;
BEGIN
SELECT sal, mgr INTO salary, mgr_num FROM emp
WHERE empno = starting_empno;
WHILE salary < 4000 LOOP
SELECT sal, mgr, ename INTO salary, mgr_num, last_name
FROM emp
WHERE empno = mgr_num;
END LOOP;
INSERT INTO temp VALUES (NULL, salary, last_name);
COMMIT;
END;
/
39

40

Les curseurs

Les curseurs
 Le traitement des ordres SQL se fait dans une zone de

travail

 PL/SQL permet de nommer cette zone mmoire et de


contrler sa gestion travers l'utilisation des curseurs
 Deux types de curseurs :
curseur implicite :
gr automatiquement par PL/SQL, les requtes ne doivent
retourner qu'une seule ligne
peu intressant

curseur explicite :
c'est un curseur qui est dfini par l'utilisateur. Il permet de traiter
les requtes SQL dont le rsultat est constitu de plusieurs lignes:
il rcupre la premire ligne de la rponse,
et garde la trace de la ligne courante pour accder aux autres lignes

42

Curseur Explicite
 Un curseur est
dclar dans la partie DECLARATION d'un bloc PL/SQL
initialis en utilisant lordre OPEN
ferm en utilisant lordre CLOSE

 Lordre FETCH est utilis pour rcuprer la ligne


courante du curseur
pour traiter plusieurs lignes il faut mettre FETCH dans une
boucle pour pouvoir lexcuter plusieurs fois;

43

Dclaration d'un curseur


Associer un nom une requte SQL
Syntaxe :
CURSOR cursor_name [(parameter[, parameter]...)]
[RETURN return_type] IS select_statement;
cursor_parameter_name [IN] datatype
[{:= | DEFAULT} expression]
return_type : doit tre un record ou une ligne

Exemple :
DECLARE
CURSOR c1 IS
SELECT empno, ename, job, sal
FROM emp
WHERE sal > 2000;
CURSOR c2 RETURN dept%ROWTYPE IS
SELECT * FROM dept WHERE deptno = 10;

n'est pas une variable PL/SQL !

44

Ouverture d'un curseur


Ordre OPEN
Quand un curseur est ouvert :
la requte est excute et
le rsultat de la requte est identifie, i.e. un
ensemble de lignes (appel result set).
Pour les curseurs dclars FOR UPDATE ces
lignes sont verrouilles
Les lignes ne sont pourtant pas disponibles
=> cf ordre fetch

Exemple :

DECLARE
CURSOR c1 IS SELECT ename, job FROM emp
WHERE sal < 3000; ...
BEGIN
OPEN c1;...
45
END;

Rcupration des lignes


L'ordre FETCH
rcupre une ligne du "result set".
Aprs chaque FETCH, le curseur avance la
ligne suivante du "result set".
Exemple :

FETCH c1 INTO my_empno, my_ename, my_deptno;

Pour chaque colonne associe la requte du


curseur, il doit y avoir une variable de type
compatible dans la liste INTO
Exemple :

LOOP
FETCH c1 INTO my_record;
EXIT WHEN c1%NOTFOUND;
-- process data record
END LOOP;

46

Fermeture d'un curseur


Ordre CLOSE
invalide le curseur
le "result set" devient indfini
Exemple :
CLOSE c1;

Une fois ferm, on peut le rouvrir


Sur un curseur ferm, toute opration
dclenche l'exception prdfinie
INVALID_CURSOR
47

Attributs d'un curseur explicite (1)


 Le curseur explicite dispose de quatre attributs qui
fournissent des informations le concernant
%NOTFOUND
valu TRUE si le dernier FETCH ne retourne
aucune ligne (il n'y a plus de ligne disponible)
valu FALSE si le dernier FETCH retourne
une ligne
%FOUND
ngation du %NOTFOUND

48

Attributs (suite)
 %ROWCOUNT retourne le nombre de lignes qui ont
t ramenes par des ordres FETCH
 %ISOPEN
valu TRUE si le curseur est ouvert,
valu FALSE si le curseur est ferm.

Utilisation des attributs


Il faut simplement faire prcder l'attribut par le
nom du curseur
Exemple:
IF emp_curs%NOTFOUND THEN
(emp_curs est le nom du curseur)
49

Exemple
Slectionner les 5 employs les mieux pays de la
table EMP
pour limiter les E/S, crer une table temporaire, e.g.
TEMP, dans laquelle on insrera le salaire, le numro
de l'employ et son nom
faire une requte SQL qui effectue "presque" tous le
travail
dclarer un curseur sur cette requte et faire une
boucle de 1 5 pour insrer le rsultat dans VALUES

50

Le curseur FOR LOOPS


 Simplification dcriture dun curseur explicite
 permet la fois
douvrir le curseur,
dexcuter des fetchs pour ramener chaque ligne retourne par
lordre SQL associ et
enfin de fermer le curseur quand toutes les lignes ont t traites.

 Syntaxe :
DECLARE
CURSOR man IS SELECT num FROM emp WHERE ;
BEGIN
FOR c IN man LOOP ...
END LOOP;
END;

 Exemple : cf. Examp7.sql


51

Curseur pour la mise jour


Un curseur peut tre utilis pour la mise
jour dune relation
Dmarche :
Dclaration du curseur
il faut prciser lintention de lutiliser pour la
mise jour laide de lordre FOR UPDATE

La structure est renseigne par le FETCH


Exemple : FETCH nom_curseur INTO nom_structure
La clause WHERE CURRENT OF permet
d'accder la ligne courante dans le
curseur

52

Exemple de curseur en MAJ


DECLARE
CURSOR employee_cur IS
SELECT * FROM employee
FOR UPDATE OF salary;
BEGIN
FOR employee_rec IN employee_cur
LOOP
UPDATE employee
SET
salary = 10000
WHERE CURRENT OF employee_cur;
END LOOP;
END;
/
53

Curseur paramtr
 Permet de rutiliser un mme curseur avec des valeurs
diffrentes dans un mme bloc PL/SQL
Syntaxe :
DECLARE
CURSOR nom_cur(P1 Type, P2 Type)
IS "ordre SQL avec les paramtres P1 et P2";
BEGIN
OPEN nom_cur(val1, val2); ...
END;
Type: CHAR, NUMBER, DATE, BOOLEAN (sans spcifier la
longueur)

 Le passage des valeurs des paramtres se fait


louverture du curseur
54

/*
**
**
**
**
*/

This
paid
many
many

block calculates the total wages (salary plus commission)


to employees in department 20. It also determines how
of the employees have salaries higher than $2000, and how
have commissions larger than their salaries.

DECLARE
CURSOR emp_cursor(dnum NUMBER) IS
SELECT sal, comm FROM emp WHERE deptno = dnum;
total_wages
NUMBER(11,2) := 0;
high_paid
NUMBER(4) := 0;
higher_comm
NUMBER(4) := 0;
BEGIN
/* The number of iterations will equal the number of rows *
* returned by emp_cursor.
*/
FOR emp_record IN emp_cursor(20) LOOP
emp_record.comm := NVL(emp_record.comm, 0);
total_wages := total_wages + emp_record.sal +
emp_record.comm;
IF emp_record.sal > 2000.00 THEN
high_paid := high_paid + 1;
END IF;
IF emp_record.comm > emp_record.sal THEN
higher_comm := higher_comm + 1;
END IF;
END LOOP;
INSERT INTO temp VALUES (high_paid, higher_comm,
'Total Wages: ' || TO_CHAR(total_wages));
COMMIT;
END;
/

55

Curseur implicite
PL/SQL permet d'accder des informations de la
dernire requte excute
La rcupration des informations se fait par
l'intermdiaire des attributs du curseur implicite
Le nom du dernier curseur non explicite est
SQL%
Exemple :
DELETE FROM emp WHERE empno = my_empno;
IF SQL%FOUND THEN -- delete succeeded
INSERT INTO new_emp VALUES (my_empno, my_ename, ...);
56

Les attributs d'un curseur implicite


 %NOTFOUND
SQL%NOTFOUND est valu
TRUE si :
un ordre INSERT, DELETE ou UPDATE, naffecte aucune ligne
un ordre SELECT ne retourne aucune ligne

FALSE si:
un ordre INSERT, DELETE ou UPDATE, affecte une ou plusieurs
lignes
un ordre SELECT retourne au moins une ligne

 %FOUND : donne la ngation de SQL%NOTFOUND


 %ROWCOUNT
Nombre de lignes affectes par un INSERT, UPDATE, ou DELETE
ou retourn par un SELECT INTO (???)
DELETE FROM emp WHERE ...
IF SQL%ROWCOUNT > 10 THEN
-- more than 10 rows were deleted
END IF;

57

PL/SQL dynamique

Ordre SQL dynamique


Ncessaire quand l'ordre excuter n'est
pas connu la compilation
plus flexible et parfois plus efficace
Ordre EXECUTE IMMEDIATE
EXECUTE IMMEDIATE dynamic_string
[INTO {define_variable[, define_variable]... | record}]
[USING [IN | OUT | IN OUT] bind_argument
[, [IN | OUT | IN OUT] bind_argument]...];

59

Exemple
DECLARE
sql_stmt
VARCHAR2(100);
plsql_block VARCHAR2(200);
my_deptno
NUMBER(2) := 50;
my_dname
VARCHAR2(15) := 'PERSONNEL';
my_loc
VARCHAR2(15) := 'DALLAS';
emp_rec
emp%ROWTYPE;
BEGIN
sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)';
EXECUTE IMMEDIATE sql_stmt USING my_deptno, my_dname, my_loc;
sql_stmt := 'SELECT * FROM emp WHERE empno = :id';
EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING 7788;
EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno=:n' USING my_deptno;
plsql_block := 'BEGIN emp_stuff.raise_salary(:id, :amt); END;';
EXECUTE IMMEDIATE plsql_block USING 7788, 500;
EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)';
sql_stmt := 'ALTER SESSION SET SQL_TRACE TRUE';
EXECUTE IMMEDIATE sql_stmt;
END;

60

61

Les exceptions

La gestion des exceptions


EXCEPTION : condition derreur qui peut tre
interne (erreur systme) ou
externe (dfinie par lutilisateur)

Lutilisateur peut dfinir ses propres


exceptions dans la partie dclarative
du bloc PL/SQL
Quand une erreur apparat, une exception est
dclenche
lexcution normale du bloc est interrompue et le
contrle est transfr la partie traitement de
lexception (exception handling) du bloc PL/SQL
63

Le branchement GOTO
 Permet de transfrer le contrle dexcution du
programme vers un BLOC ou vers une dclaration
excutable
 Lutilisation des labels permet de marquer des points
dans le programme PL/SQL ou lordre GOTO peut
faire des branchements
Les branchements suivants sont interdits:
faire un branchement dans une squence d'instructions (boucle
FOR par exemple) de l'extrieur de cette squence
faire un branchement dans la partie traitement d'une exception
faire un branchement partir de la partie traitement d'une
exception vers le bloc courant
64

Dclenchement
Exception Interne
Dclenche automatiquement par le systme

Exception Externe
Dclenche explicitement par l'utilisateur par la
commande RAISE
 Traitement dune exception
Le traitement de lexception est dfini dans une routine
appele "exception handlers" dclare la fin du bloc
PL/SQL
Aprs lexcution du traitement dune exception, le contrle
est donn au bloc suprieur sil existe sinon il est donn
lenvironnement hte

 Cf. examp11.sql
65

Exemples
DECLARE
xnum NUMBER(3,1);
yvar NUMBER(3,1);
test1 exception;
- - Dclaration d'une exception externe
. . .
BEGIN
. . .
RAISE test1;
- - Dclenchement de l'exception test1
xnum:= 15/yvar;
- - Erreur systme si yvar = 0
. . .
. . .
EXCEPTION
WHEN test1 THEN . . .; - - Traitement de l'exception externe test1
WHEN ZERO-DIVIDE THEN . . .;
/* Traitement de l'exception interne
dclenche lors d'une division par zro*/
WHEN others THEN . . .; - - Traitement des autres exceptions
END;

66

Quelques remarques
 La clause optionnelle OTHERS dfinie un
branchement pour toutes les exceptions qui ne sont
pas explicitement prise en charge dans la partie
traitement de l'exception
 Il existe des exceptions internes qui sont prdfinis
par le systme (elles ont dj un nom et il nest pas
ncessaire de les dclarer)
Exemple : ZERO-DIVIDE

 Les exceptions internes peuvent tre nommes (ou


renommes)
 erreurs ORACLE : cf Error Messages and Codes
67

Propagation des
exceptions
Si une exception est dclenche et que son
traitement nest pas dfini dans le BLOC
courant, alors lexcution du BLOC courant
est arrte et lexception est propage au
BLOC suprieur qui devient le BLOC courant
Si le traitement dune exception nest dfini
dans aucun BLOC, lexception est propage
jusquau dernier BLOC puis un message
d'erreur unhandled exception est renvoy
lenvironnement hte
68

Propagation des exceptions


Environnement Hote

BEGIN
...
BEGIN
If xvar= 1 then
RAISE A
If xvar= 1 then
RAISE B;
If xvar= 1 then
RAISE C;
EXCEPTION
When A Then
...
END;

...
EXCEPTION
When B Then
...
END;

B est
dclenche
Le contrle est
pass au bloc
suprieur

Propagation de B

Le contrle passe l'environnement hote

69

Porte des exceptions


Si une exception est dclare dans un bloc, elle
est :
locale au BLOC
globale pour les SOUS-BLOCS.

Un BLOC ne peut rfrencer que les exceptions


globales ou locales (il ne peut rfrencer les
exceptions de ses SOUS-BLOCS)
Une exception globale peut tre redclare
dans un SOUS-BLOC (dans ce cas le SOUSBLOC ne peut plus rfrencer lexception
globale)
70

DECLARE
A EXCEPTION;
BEGIN
BEGIN
. . .
IF . . . THEN
RAISE A;
END IF; . . .
EXCEPTION
WHEN A THEN
. . .
RAISE A;
END

- - Dbut du sous-bloc

- - Fin du sous-bloc

. . .
EXCEPTION
WHEN A THEN . . . ;
END;

71

Bref rappels sur les


transactions
 Une transaction est une srie doprations de MAJ
des donnes en SQL (insert, update, delete)
 Le dbut dune transaction est IMPLICITE alors que
la fin doit tre EXPLICITE :
3 principaux ordres
COMMIT : termine la transaction en rendant les changements
permanents,
ROLLBACK : termine la transaction en annulant les
changements effectus. Le ROLLBACK permet de faire des
retours arrires (en cas d'erreurs ou d'interruptions),
ROLLBACK TO: permet de revenir des points initialement
marqus par un SAVEPOINT
SAVEPOINT : marque le point courant dans le traitement de la
transaction.
72

Transactions et PL/SQL
Toujours souhaitable de terminer un programme
PL/SQL par
un COMMIT et/ou un ROLLBACK
aprs excution du bloc, le contrle revient
lenvironnement hte ou au programme appelant

Impossible de mettre un COMMIT dans une


boucle FETCH lors du traitement d'un CURSEUR
avec la clause FOR UPDATE
la boucle FETCH place les verrous de mise jour
alors que le COMMIT a pour effet de relcher les
verrous.
on obtient le message d'erreur fetch out of sequence
73

Les sous-programmes

Les sous-programmes
Blocs PL/SQL nomms avec paramtres
Deux types de sous programmes
Procdures
Fonctions

Passage de paramtres
classiques aux LP

Notion de surcharge et de
polymorphisme
75

Procdures : syntaxe
 Syntaxe
procedure ::=
PROCEDURE name [(parameter[, parameter, ...])] IS
[local declarations]
BEGIN
executable statements
[EXCEPTION
exception handlers]
END [name];

parameter ::=
parameter_name [IN | OUT [NOCOPY] | IN OUT [NOCOPY]]
datatype_name [{:= | DEFAULT} expression]

 Exemple : Procedure p (a char)


 Le type des paramtres formels ne peut pas tre restreint
Procedure p (a char(20)) illicite

 Appel de procdure : comme en Pascal, C ...


76

Exemples
CREATE PROCEDURE sam.credit (acc_no IN NUMBER, amount IN NUMBER) IS
BEGIN
UPDATE accounts
SET balance = balance + amount
WHERE account_id = acc_no;
END;
CREATE PROCEDURE raise_salary (emp_id INTEGER, amount REAL) IS
current_salary REAL;
salary_missing EXCEPTION;
BEGIN
SELECT sal INTO current_salary FROM emp WHERE empno = emp_id;
IF current_salary IS NULL THEN RAISE salary_missing;
ELSE UPDATE emp SET sal = sal + amount WHERE empno = emp_id;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO emp_audit VALUES (emp_id, 'No such number');
WHEN salary_missing THEN
INSERT INTO emp_audit VALUES (emp_id, 'Salary is null');
END raise_salary;
77

Les fonctions
 Retourne un rsultat
 Syntaxe : idem une procdure sauf la clause RETURN
FUNCTION name [(parameter[, parameter, ...])]
RETURN datatype IS

 Les fonctions ne peuvent pas tre utilises dans des instructions


SQL
Exemple : insert into EMP values (, ma_fct())
illicite

 L'instruction "return"

finit l'execution de la fonction


retourne sous le contrle du programme appelant

 Si pas de return :
exception PROGRAM-ERROR est leve

78

Exemple
CREATE FUNCTION get_bal(acc_no IN NUMBER)
RETURN NUMBER
IS acc_bal NUMBER(11,2);
BEGIN
SELECT balance
INTO acc_bal
FROM accounts
WHERE account_id = acc_no;
RETURN(acc_bal);
END;

79

Les modes des paramtres


Trois modes : IN (par dfaut), OUT, INOUT
 IN

Permet de transmettre des valeurs au programme appel


se comporte comme une constante
n'apparat pas en partie gauche d'une affectation
pas d'effet de bord dans le programme appelant

 OUT :

permet de modifier la valeur d'une variable


ne permet pas de transmettre des valeurs au programme appel
pas de calcul avec ce paramtre dans le programme appel

 INOUT :

Permet de transmettre des valeurs au programme appel et aussi de


les modifier

 Les paramtres par dfauts :

Permet de spcifier des valeurs par defaut


Donne plus de souplesse lors de l'appel de la procdure ou de la
fonction

 Option NOCOPY

Force un passage de paramtres par rfrence pour viter de copier


les objets volumineux
80

Les packages

Les Packages
Permet de regrouper dans un mme "espace"
logique des variables, des types et des sous
programmes
Ressemble la notion de librairie ou d'espace de
nommage
Exemple de package : SQL*Plus

Doivent tre conus en quipe


Amliorent les performances globales de
l'application
Obligent des conventions de nommage et la
gestion concerte d'une application
82

Packages (suite)
Objet de la BD comme l'est une relation ...
Regroupe de manire logique
les types PL/SQL dclars,
les objets et
les sous programmes

Deux parties :
spcification : partie dclarative (e.g. .h en C++)
corps : partie dfinition (e.g. .cpp en C++)
83

Packages : syntaxe
CREATE [OR REPLACE] PACKAGE package_name
[AUTHID {CURRENT_USER | DEFINER}] {IS | AS}
[type_definition [type_definition] ...]
[cursor_spec [cursor_spec] ...]
[item_declaration [item_declaration] ...]
[{subprogram_spec | call_spec} [{subprogram_spec |
call_spec}]...]
END [package_name];
[CREATE [OR REPLACE] PACKAGE BODY package_name {IS | AS}
[type_definition [type_definition] ...]
[cursor_body [cursor_body] ...]
[item_declaration [item_declaration] ...]
[{subprogram_spec | call_spec} [{subprogram_spec |
call_spec}]...]
[BEGIN
sequence_of_statements]
END [package_name];]

84

CREATE PACKAGE emp_actions AS -- spcification du package


PROCEDURE hire_employee (emp_id INTGER, name VARCHAR2, ...);
PROCEDURE fire_employee (emp_id INTEGER);
PROCEDURE raise_salary (emp_id INTEGER, amount REAL);
END emp_actions;
CREATE PACKAGE BODY emp_actions AS -- package body
PROCEDURE hire_employee (emp_id INTGER, name VARCHAR2, ...) IS
BEGIN ...
INSERT INTO emp VALUES (empno, ename, ...);
END hire_employee;
PROCEDURE fire_employee (emp_id INTEGER) IS
BEGIN
DELETE FROM emp WHERE empno = emp_id;
END fire_employee;
PROCEDURE raise_salary (emp_id INTEGER, amount REAL) IS
salary REAL;
BEGIN
SELECT sal INTO salary FROM emp WHERE empno = emp_id;
...
END raise_salary;
END emp_actions;
85

86

Les triggers

Triggers
Ne font pas partie du langage PL/SQL,
utilisent juste le langage
Programme PL/SQL mmoris
associ une table, un schma ou la base de
donnes
Sur une table, le programme s'excute
lorsqu'une opration de mise jour y est faite

Diffrence avec les sous programmes ?


Ils sont invoqus implicitement lors des MAJ
(au sens large) de la BD
=> permettent de coder des contraintes
88
d'intgrits, de faire de l'audit ...

ECA :
Evnement/condition/Action
Le paradigm ECA
Event: vnement qui active le trigger
Condition: une requte ou un test qui est
excut quand le trigger se dclenche
Action: une procdure qui est excute
quand le trigger est activ et que la
condition est vrai.

Quand est ce que le trigger s'excute


par rapport au dclenchement de
l'vnement ?
89

Triggers (suite)
Faire attention aux actions faites par un
trigger
les "droits" du trigger sont ceux de son
concepteur
lors d'une MAJ de la BD par un utilisateur
lambda, le trigger peut se dclencher sans
que les droits de l'un correspondent aux
droits de l'autre !
90

Exemple de triggers de MAJ


 CREATE TRIGGER scott.emp_permit_changes
BEFORE
DELETE OR INSERT OR UPDATE
ON scott.emp
pl/sql block

Oracle dclenche ce trigger quand un DELETE,


INSERT, ou UPDATE affecte la table EMP dans le
schma de SCOTT.
Le trigger EMP_PERMIT_CHANGES est un trigger
BEFORE, donc Oracle le dclenche avant l'excution
de l'ordre de MAJ.
91

Exemple de trigger de MAJ avec


restriction
 CREATE TRIGGER scott.salary_check
BEFORE
INSERT OR UPDATE OF sal, job ON scott.emp
FOR EACH ROW
WHEN (new.job <> 'PRESIDENT')
pl/sql_block

Oracle dclenche le trigger quand sur la table


EMP :
un INSERT est effectu
un UPDATE change la valeur de SAL ou de JOB

SALARY_CHECK est un trigger BEFORE row, donc


Oracle le dclenche
avant le changement d'une ligne qui est mise jour par
l'UPDATE ou
avant l'ajout d'une ligne qui est insre par l'INSERT
92

Exemple
CREATE TRIGGER init_count BEFORE INSERT ON Students
DECLARE
Evnement
count INTEGER
Statement BEGIN
level
Action
count:= 0
END
CREATE TRIGGER incr_count AFTER INSERT ON Students
WHEN (new.age < 18)
FOR EACH ROW
Condition
BEGIN
Row
count:= count+1
level
END

code Oracle PL/SQL


execut pour chaque
ligne modifie
93

Appel de procdure dans un


trigger
 CREATE TRIGGER scott.salary_check
BEFORE INSERT OR UPDATE OF sal, job ON scott.emp
FOR EACH ROW
WHEN (new.job<> 'PRESIDENT')
CALL check_sal(:new.job, :new.sal, :new.ename);

La procdure CHECK_SAL peut tre


implmente en PL/SQL, C, ou Java.
On peut spcifier des valeurs :OLD dans la
clause la place des valeurs :NEW.

94

Exemple de trigger de BD
Cration d'un trigger qui trace toutes les
erreurs
trigger AFTER, i.e. il est dclench aprs une
excution illicite (e.g. erreur de connexion)
CREATE TRIGGER log_errors AFTER SERVERERROR ON DATABASE
BEGIN
IF (IS_SERVERERROR (1017)) THEN
<special processing of logon error>
ELSE
<log error number>
END IF;
END;

95

Exemple de Trigger de schma


Cration d'un trigger AFTER sur tout ordre
SQL CREATE.
Permet l'audit de cration de nouveaux
objets dans un schma
CREATE TRIGGER audit_db_object AFTER CREATE
ON SCHEMA
pl/sql_block

96

Exemple de trigger INSTEAD OF


CREATE TABLE customers_sj
CREATE TYPE customer_t AS OBJECT
( cust
NUMBER(6),
( cust
NUMBER(6),
address VARCHAR2(50),
address
VARCHAR2(50),
credit
NUMBER(9,2) );
credit
NUMBER(9,2),
location
VARCHAR2(20) );
CREATE TABLE customers_pa
( cust
NUMBER(6),
address VARCHAR2(50),
credit
NUMBER(9,2) );
CREATE VIEW all_customers (cust)
AS SELECT customer_t (cust, address, credit, 'SAN_JOSE')
FROM
customers_sj
UNION ALL
SELECT customer_t (cust, address, credit, 'PALO_ALTO')
FROM
customers_pa;

CREATE TRIGGER instrig INSTEAD OF INSERT ON all_customers


FOR EACH ROW
BEGIN
IF (:new.cust.location = 'SAN_JOSE') THEN
INSERT INTO customers_sj
VALUES (:new.cust.cust, :new.cust.address,:new.cust.credit);
ELSE
INSERT INTO customers_pa
VALUES (:new.cust.cust, :new.cust.address, :new.cust.credit);
END IF;
97
END;

98

Conclusion

PL/SQL en bref
Langage de programmation classique
+ des ordres SQL
notion de curseurs pour "travailler" sur des
lignes du rsultat d'une requte

Utilis pour dfinir des triggers et des


procdures stockes
LP similaires :
Pro*C, Pro*Cobol
ODBC avec C, C++, Java, VB
100

Вам также может понравиться