Академический Документы
Профессиональный Документы
Культура Документы
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
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, ...
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
Le SQL admis
Dclaration des manipulations de donnes
INSERT, SELECT, UPDATE, DELETE
CONVERSION
Prdicats SQL
utiliss dans la clause WHERE (and, or, not) et
les oprateurs de comparaison between, in, is null,
like
10
Limites :
Primitives d'E/S faibles,
tableaux limits
11
12
Blocs PL/SQL
14
15
Types de donnes
Classique aux LPs :
Types scalaires :
tous les types de base usuels
Types composs :
tableaux et enregistrements
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
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;
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;
21
22
Conventions syntaxiques
Conventions de nommage
tre rigoureux, explicite, fidle !!!
23
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
Oracle V8
27
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;
Exemple :
DECLARE
TYPE DeptRecTyp IS RECORD
(depno NUMBER(2) NOT NULL,
dname dept.dname%type,
loc dept.loc%type);
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
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
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
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
43
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;
44
Exemple :
DECLARE
CURSOR c1 IS SELECT ename, job FROM emp
WHERE sal < 3000; ...
BEGIN
OPEN c1;...
45
END;
LOOP
FETCH c1 INTO my_record;
EXIT WHEN c1%NOTFOUND;
-- process data record
END LOOP;
46
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.
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
Syntaxe :
DECLARE
CURSOR man IS SELECT num FROM emp WHERE ;
BEGIN
FOR c IN man LOOP ...
END LOOP;
END;
52
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)
/*
**
**
**
**
*/
This
paid
many
many
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
FALSE si:
un ordre INSERT, DELETE ou UPDATE, affecte une ou plusieurs
lignes
un ordre SELECT retourne au moins une ligne
57
PL/SQL dynamique
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
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
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
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
69
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
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
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]
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
L'instruction "return"
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
OUT :
INOUT :
Option NOCOPY
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
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
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
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.
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
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
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
96
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