0% ont trouvé ce document utile (0 vote)
288 vues66 pages

Cours sur PL/SQL et Gestion de DB

Ce document décrit les principes de base de PL/SQL, y compris la structure d'un programme PL/SQL, les variables, les types de données, les structures de contrôle et les curseurs.

Transféré par

Ayman Bahloul
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
288 vues66 pages

Cours sur PL/SQL et Gestion de DB

Ce document décrit les principes de base de PL/SQL, y compris la structure d'un programme PL/SQL, les variables, les types de données, les structures de contrôle et les curseurs.

Transféré par

Ayman Bahloul
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

SUPPORT DE COURS

SYSTEME DE GESTION DE BASE DE DONNEES

Public cible: INF2

Charge horaire semestrielle par semaine:


30h cours
15h TP

Objectifs du cours:
Ecrire des programmes modulaires en
utilisant les procédures, les fonctions
et les packages.
Contrôle des événements à l’aide des
déclencheurs.

Pré-requis du cours:
Algorithmique
Base de données
Le langage SQL
1
SOMMAIRE
1. INTRODUCTION

2. STRUCTURE D’UN PROGRAMME

3. STRUCTURES DE CONTRÔLE

4. LES CURSEURS

5. LES EXCEPTIONS

6. LES SOUS_PROGRAMMES

7. LES PACKAGES

8. LES DECLENCHEURS

9. ADMINISTRATION 2
1. INTRODUCTION

Pourquoi PL/SQL ?

 SQL est un langage non procédural

 Les traitements complexes sont parfois très


difficiles à écrire si on ne peut utiliser des
variables et des 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 des structures de
programmation habituelles
3
Principales caractéristiques de PL/SQL

 Extension de SQL : des requêtes SQL


cohabitent avec les structures de contrôle
habituelles de la programmation structurée
(blocs, alternatives, boucles)

 Un programme est constitué de procédures


et de fonctions

 Des variables permettent l’échange


d’information entre les requêtes SQL et le
reste du programme

4
Utilisation de PL/SQL

 PL/SQL peut être utilisé pour l’écriture des


procédures stockées et des triggers

 Il convient aussi pour écrire des fonctions


utilisateurs qui peuvent être utilisées
dans les requêtes SQL (en plus des
fonctions prédéfinies)

5
2. STRUCTURE D’UN PROGRAMME

DECLARE

-- définitions de variables

BEGIN

-- Les instructions à exécuter

EXCEPTION

-- La récupération des erreurs

END;
/

6
LES VARIABLES

Identificateurs Oracle :
30 caractères au plus
commence par une lettre
peut contenir lettres, chiffres, _, $ et #
Pas sensible à la casse
Doivent être déclarées avant d’être utilisées

Commentaires :
-- Pour une ligne
/* Pour plusieurs lignes */

7
Types de variables

Les types habituels correspondants aux types


Oracle : number, char,…

Types composites adaptés à la récupération


des colonnes et lignes des tables SQL :
%TYPE, %ROWTYPE

8
Déclaration d’une variable

identificateur [CONSTANT] type [:= valeur];

Exemples :
age number;
nom varchar(30);
dateNaissance date;
ok boolean := true;

Déclarations multiples interdites :


i, j number;

9
Déclaration %TYPE

On peut déclarer une variable du même type qu’une


colonne d’une table

nom emp.nom%TYPE;

Déclaration %ROWTYPE

Une variable peut contenir toutes les colonnes


d’une table

employe emp%ROWTYPE;

10
Exemple d’utilisation

declare
employe emp%ROWTYPE;
begin
select * into employe from emp
where empno=7369;
insert into emp(empno,ename) values
(44,employe.ename);
end;
/

11
Type RECORD

Equivalent à struct du langage C

TYPE nomRecord IS RECORD


(
champ1 type1,
champ2 type2,
…);

12
Utilisation du type RECORD

declare
type employes is record
(empno number(4),
ename char(10)
);
employe employes;
begin
select empno, ename into employe
from emp
where empno=7369;
insert into emp(empno,ename) values
(45,employe.ename);
end;
/
13
Type TABLE
TYPE nomTable IS TABLE of type INDEX BY
BINARY_INTEGER;

Utilisation du type TABLE


declare
type employes is table of varchar2(25) index by
binary_integer;
employe employes;
begin
select ename,job into employe(1), employe(2)
from emp
where empno=7369;
insert into emp(empno,ename,job) values
(48,employe(1), employe(2));
end;
14
Affectation

deux façons d’affecter une valeur à une


variable :

 :=
 par la directive INTO de la requête SELECT

Exemples :

 wdate := ’10/10/2004’;
 select ename INTO wnom
from emp
where empno = 7369;
15
3. STRUCTURES DE CONTRÔLE
Structures alternatives
 IF condition THEN
instructions;
END IF;
Exemple:
declare
wsal number(10,3);
begin
select sal into wsal
from emp where empno=7369;
if wsal<500 then
update emp set sal=sal*1.1
where empno=7369;
end if;
end;
/
16
 IF condition THEN
instructions1;
ELSE
instructions2;
END IF;
Exemple:
declare
wsal number(10,3);
begin
select sal into wsal
from emp where empno=7369;
if wsal<500 then
update emp set sal=sal*1.1 where empno=7369;
else
update emp set sal=sal*1.05
where empno=7369;
end if;
end;
/
17
 IF condition1 THEN
instructions1;
ELSEIF condition2 THEN
instructions2;
ELSEIF …

ELSE
instructionsN;
END IF;

18
declare
wsal number(10,3);
begin
select sal into wsal
from emp
where empno=7369;

if wsal<500 then
update emp set sal=sal*1.1
where empno=7369;
elsif wsal<900 THEN
update emp set sal=sal*1.05
where empno=7369;
else
update emp set sal=sal*1.02
where empno=7369;
end if;
end;
19
Structures répétitives
Boucle « tant que »

WHILE condition LOOP


instructions;
END LOOP;
Exemple:
declare
i number:=0;
s number :=0;
begin
while i<=9 loop
s:=s+i;
i:=i+1;
end loop;
end;
/
20
Boucle « jusqu’à »
LOOP
instructions;
EXIT [WHEN condition];
END LOOP;

Exemple:
declare
i number:=0;
s number :=0;
begin
loop
s:=s+i;
i:=i+1;
exit when i=10;
end loop;
end;
/
21
Boucle « pour »

FOR compteur IN [REVERSE] inf..sup LOOP


instructions;
END LOOP;

Exemple :

declare declare
s number :=0; s number :=0;
begin begin
for i in 0..9 loop for i in reverse 1..9 loop
s:=s+i; s:=s+i;
end loop; end loop;
end; end;
/ /

22
Mise au point

Pour la mise au point il est utile de faire


afficher les valeurs des variables

On peut le faire en activant sous SQL*PLUS


la sortie sur l’écran et en utilisant le
paquetage DBMS_OUTPUT

Un paquetage est un regroupement de


procédures et de fonctions

23
Exemple:

set serveroutput on
declare
s number :=0;
begin
for i in reverse 1..9 loop
s:=s+i;
end loop;
dbms_output.put_line (s);
end;
/

24
4. LES CURSEURS

Fonctionnalités

Toutes les requêtes SQL sont associées à un


Curseur

 Ce curseur représente une zone mémoire


utilisée pour exécuter une requête

 Le curseur peut être implicite ou explicite (déclaré


par l’utilisateur)

 Les curseurs explicites servent à retourner


plusieurs lignes

25
Attributs des curseurs

Tous les curseurs ont des attributs que


l’utilisateur peut utiliser

 %ROWCOUNT : nombre de lignes traitées


par la requête

 %FOUND : vrai si au moins une ligne a été Traitée

 %NOTFOUND : vrai si aucune ligne n’a été traitée

 %ISOPEN : vrai si le curseur est ouvert

26
Curseur implicite

 Un curseur implicite est toute commande SQL


(select, insert, update, delete) située dans la partie
BEGIN.

 Un curseur implicite ne possède pas de nom

 Son nom est toujours SQL.

27
Exemple:
declare
wempno emp.empno%type;
wename emp.ename%type;
begin
select empno, ename into wempno, wename
from emp
where empno=7369;
dbms_output.put_line(wempno||wename);
end;
/

Exception du curseur implicite select into:

• NO_DATA_FOUND: aucune ligne n’est traitée


• TOO_MANY_ROWS : résultat formé de plusieurs
lignes
28
Conséquence d’exception

En cas d’exception non gérée par le développeur,


le système engendre un échec en abandonnant le
reste de l’exécution du bloc.

29
Remarque:
Avec les curseurs implicites de mise à jour
(update, delete et insert) le problème ne se pose
pas en cas de:
 aucune ligne n’est traitée
 résultat formé de plusieurs lignes
Exemple1:
begin
delete from dept where deptno=345;
dbms_output.put_line(sql%rowcount);
end;
/

30
Exemple2:

begin
delete from a;
dbms_output.put_line(sql%rowcount);
if (sql%notfound) then
dbms_output.put_line('pas de lignes');
end if;
end;
/

31
Curseur explicite

 Pour traiter les select qui renvoient plusieurs


lignes

 Ils doivent être déclarés

 Ils doivent être utilisés explicitement avec les


ordres OPEN, FETCH et CLOSE ou bien avec FOR

 Le plus souvent on les utilise dans une boucle


dont on quitte quand l’attribut NOTFOUND
du curseur est vrai

32
Syntaxe
DECLARE
CURSOR nom_curseur[(liste de paramètres)] IS
Commande select
[FOR UPDATE OF COLONNE1,…?COLONNE N];

BEGIN

OPEN nom_curseur[(liste de FOR enreg IN nom_curseur[(liste de


paramètres)]; paramètres)]LOOP
LOOP
FETCH nom_curseur INTO variables; …..
EXIT WHEN
nom_curseur%NOTFOUND; ;
END LOOP; END LOOP;
CLOSE nom_curseur.

END;
33
Exemple avec fetch(curseur non paramétré)
declare
cursor fonctions is
select distinct job
from emp;
v_job fonctions%rowtype;
begin
open fonctions;
loop
fetch fonctions into v_job;
exit when fonctions%notfound;
dbms_output.put_line(v_job.job);
end loop;
close fonctions;
end;
/
34
Exemple avec fetch (curseur paramétré)

declare
cursor fonctions(wdept dept.deptno%type) is
select distinct job
from emp
where deptno=wdept;

v_job fonctions%rowtype;
begin
open fonctions(10);
loop
fetch fonctions into v_job;
exit when fonctions%notfound;
dbms_output.put_line(v_job.job);
end loop;
close fonctions;
end;
/
35
Exemple avec for (curseur non paramétré)

declare
cursor fonctions is
select distinct job
from emp;
begin
for enreg in fonctions loop
dbms_output.put_line(enreg.job);
end loop;
end;
/

36
Exemple avec for (curseur paramétré)

declare
cursor fonctions(wdept dept.deptno%type) is
select distinct job
from emp
where deptno=wdept;

begin
for enreg in fonctions(&wd) loop
dbms_output.put_line(enreg.job);
end loop;
end;
/

37
Modification d’une ligne courante d’un curseur

 Pour modifier une ligne courante d’un curseur


lors de son parcours on peut utiliser la clause
« WHERE CURRENT OF » pour désigner cette ligne.

 Pour utiliser cette technique il faut déclarer le


curseur avec la clause FOR UPDATE OF.

38
Exemple avec FETCH

declare
cursor employes is select empno, ename, sal, comm
from emp where deptno = 10
for update of emp.sal;
enreg_emp employes %rowtype;
begin
open employes ;
loop
fetch employes into Enreg_emp;
exit when employes %notfound;

if enreg_emp.comm is null then


update emp set sal=sal*1.1
where current of employes ;
end if;
end loop;
close employes ;
end;
39
Exemple avec FOR

declare
cursor employes is select empno, ename,
sal, comm
from emp where deptno = 10
for update of emp.sal;
begin
for Enreg_emp in employes loop
if enreg_emp.comm is null then
update emp set sal=sal*1.1
where current of employes ;
end if;
end loop;
end;
/

40
5. LES EXCEPTIONS

Une exception est une erreur rencontrée au moment


de l’exécution d’un bloc PL/SQL

 On distingue 2 types d’exception :

prédéfinies par Oracle (internes)


définies par le programmeur (externes)

41
Liste des exceptions prédéfinies :

Exception prédéfinie Erreur Oracle Valeur de SQLCODE


ACCESS_INTO_NULL ORA-06530 -6530
CASE_NOT_FOUND ORA-06592 -6592
COLLECTION_IS_NULL ORA-06531 -6531
CURSOR_ALREADY_OPEN ORA-06511 -6511
DUP_VAL_ON_INDEX ORA-00001 -1
INVALID_CURSOR ORA-01001 -1001
INVALID_NUMBER ORA-01722 -1722
LOGIN_DENIED ORA-01017 -1017
NO_DATA_FOUND ORA-01403 +100
NOT_LOGGED_ON ORA-01012 -1012
PROGRAM_ERROR ORA-06501 -6501

42
Exception prédéfinie Erreur Oracle Valeur de SQLCODE
ROWTYPE_MISMATCH ORA-06504 -6504
SELF_IS_NULL ORA-30625 -30625
STORAGE_ERROR ORA-06500 -6500
SUBSCRIPT_BEYOND_COUNT ORA-06533 -6533
SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 -6532
SYS_INVALID_ROWID ORA-01410 -1410
TIMEOUT_ON_RESOURCE ORA-00051 -51
TOO_MANY_ROWS ORA-01422 -1422
VALUE_ERROR ORA-06502 -6502
ZERO_DIVIDE ORA-01476 -1476

Toutes les autres exceptions doivent être traitées par leur


code erreur numérique.

43
Exemple sans exception:

declare
wename emp.ename%type;
begin
select ename into wename
from emp
where empno=1;
dbms_output.put_line(wename);
end;
/

ORA-01403: Aucune donnée trouvée

44
Exemple(1) avec exception:

declare
wename emp.ename%type;
begin
select ename into wename
from emp
where empno=1;
dbms_output.put_line(wename);
exception
When no_data_found then
Dbms_output.put_line('Numéro inexistant');
end;
/
Numéro employé inexistant
Procédure PL/SQL terminée avec succès.

45
Exemple(2) avec exception:
declare
wename emp.ename%type;
begin
select ename into wename
from emp
where empno=1;
dbms_output.put_line(wename);
exception
When others then
dbms_output.put_line( 'Code erreur : ' ||SQLCODE );
dbms_output.put_line( 'Code erreur : ' ||SQLERRM );
end;
/

Code erreur : 100


Code erreur : ORA-01403: Aucune donnée trouvée
Procédure PL/SQL terminée avec succès.

46
Exemple(3) avec exception:
declare
wename emp.ename%type;
begin
begin
select ename into wename
from emp where empno=1;
exception
when no_data_found then
dbms_output.put_line( 'Code : ' ||SQLCODE );
dbms_output.put_line( 'Code : ' ||SQLERRM );
end;
begin
select ename into wename
from emp where empno=7369;
dbms_output.put_line(wename);
exception
when others then null;
end;
end;
47
PRAGMA EXCEPTION_INIT

Nous pouvons associer un code erreur Oracle


à nos propres variables exception à l'aide du mot clé
PRAGMA EXCEPTION_INIT:

Nom_exception EXCEPTION ;
PRAGMA EXCEPTION_INIT(nom_exception, -
code_error_oracle);

Exemple :
Lorsque on insère une valeur plus longue que la taille
d’une chaine, Oracle déclenche une erreur -6502.
Nous allons "nommer" cette erreur en Val_trop_grand

48
Exemple:
Declare
V varchar2(3) ;
Val_trop_grand exception ;
pragma exception_init(Val_trop_grand, -6502 ) ;
Begin
v := 'smith';
Exception
when Val_trop_grand then
dbms_output.put_line( 'Chaîne trop longue') ;
End ;
/

Chaîne trop longue


Procédure PL/SQL terminée avec succès.

49
Exception de l’utilisateur

En plus des erreurs Oracle, nous pouvons traiter nos propres


erreurs en déclarant des variables de type exception et qui
vont être déclenchées par l'instruction RAISE
Syntaxe
DECLARE
Nom_exception Exception ;

BEGIN
…..
Raise Nom_exception ;

EXCEPTION
WHEN Nom_exception Then……….
END ;

50
Exemple:

Declare
v varchar2(3) ;
x varchar2(10) ;
slim exception;
Begin
x := &w;
if length(x)>3 then
raise slim;
else
v:=x;
end if;
Exception
when slim then
raise_application_error(-20001, 'Chaîne trop longue') ;
End ;

51
6. LES SOUS PROGRAMMES
LES FONCTIONS STOCKÉES

create or replace FUNCTION(<liste paramètres>)RETURN <type retour> IS


-- déclaration des variables
BEGIN
-- code de la fonction
END;

Exemple1:
Create or replace function somme(n1 number, n2 number) return number is
S number;
Begin
S:=n1+n2;
Return(s);
End;

52
Exemple2:
Create or replace function majorer(wsal number) return number is
sal_maj number;
Begin
sal_maj:=wsal*1.1;
Return(sal_maj);
End;
/
Utilisation
 Update emp set sal=majorer(sal);
 Select majorer(10) from dual;

53
LES PROCEDURES STOCKÉES

create or replace procedure(<param1 [in/out/in out] type [:=val/default val],


Param_i…) is
-- déclaration des variables
BEGIN
-- code de la procédure
END;

Exemple1:
Create or replace procedure somme(n1 in number, n2 in number, s out
number) is
Begin
s:=n1+n2;
End;

54
Utilisation
declare
s number;
begin
somme(10,12,s);
dbms_output.put_line(s);
end;

Exemple de fonction non stockée


declare
w number;
function somme2(n1 number,n2 number) return number is
s number;
begin
s:=n1+n2;
return (s);
end;
begin
w:=somme2(5,6);
dbms_output.put_line(w);
end;

55
Exemple de procédure non stockée

Declare

w number;
procedure somme2(n1 number,n2 number, s out number) is
begin
s:=n1+n2;
end;

begin
somme2(5,6,w);
dbms_output.put_line(w);
end;
/

56
LES PACKAGES

Un paquetage est un ensemble de procédures, de fonctions, de


variables, de constantes…regroupées dans un objet nommé.
Ces éléments sont regroupés car ils sont souvent utilisés ensemble.

Un paquetage est organisé en deux parties distinctes:

 Une partie spécification

Permet de spécifier à la fois des fonctions et des procédures ainsi


que des déclarations des types, variables, constantes, exceptions et
curseurs utilisés dans le paquetage.

 Une partie corps

Contient les blocs et les spécifications de tous les objets listés dans
la partie spécification.

57
Création de la partie spécification
create [or replace] package nom_de_package is/as
Function f1(..... ) return type_de_base;
…..
Function fn(…..) return type_de_base;
…..
Procedure p1(…..);
…..
Procedure pn(…..);
…..
End [nom_de_package]

Exemple:
Create or replace package p1 is
function majorer(wsal number) return number;
Procedure somme(n1 in number, n2 in number, s out number);
End p1;

58
Création de la partie corps
create [or replace] package body nom_de_package is/as

{Declaration de variables};
Function f1(..... ) return type_de_base is…;
…..
Function fn(…..) return type_de_base is …;
…..
Procedure p1(…..) is …;
…..
Procedure pn(…..)is …;
…..
[Begin
…]
End [nom_de_package]

59
Exemple:
Create or replace package body p1 is
function majorer(wsal number) return number is
sal_maj number;
Begin
sal_maj:=wsal*1.1;
Return(sal_maj);
End;
Procedure somme(n1 in number, n2 in number, s out number) is
Begin
s:=n1+n2;
End;
End p1;
/
Utilisation:
select p1.majorer(5) from dual;
variable x number;
execute p1.somme(3,4,:x);

60
LES DECLENCHEURS
Un trigger est un bloc PL/SQL qui s’exécute implicitement à chaque fois
qu’un événement spécifique se produit.

 Temporisation du trigger : BEFORE ou AFTER

 Evénement déclencheur : INSERT,UPDATE ou DELETE

 Nom de la table : la table sur laquelle le trigger est défini

Syntaxe de création :

CREATE [OR REPLACE] TRIGGER trigger_name


Before/after delete/update/insert
On table_name
For each row
Declare
trigger_body
End;

61
Au moment de déclenchement d’un trigger, ORACLE offre deux
pseudo records : OLD et NEW de même structure que la table du
déclencheur, contenant respectivement les anciennes et les
nouvelles valeurs de l’enregistrement en cours.

Exemple1:
create or replace trigger archive_emp
before delete /* ou bien before*/
on emp
for each row
Begin
Dbms_output.put_line('suppression du client :'||:old.ename);
insert into archive
values(:old.empno,:old.ename,:old.job,:old.MGR,:old.HIREDATE,
:old.SAL,:old.COMM,:old.DEPTNO);
end;
/

62
Exemple2:
create or replace trigger insert_dept
before insert
on dept
for each row
Declare
Wdept number;
X number;
Cursor c is select deptno from dept where deptno =:new.deptno;
Begin
Open c;
Fetch c into x;
If c%found then
raise_application_error(-20009,'erreur d insertion');
End if;
Close c;
end;
/

63
Exemple3:

CREATE OR REPLACE TRIGGER comm


BEFORE INSERT OR UPDATE
OF comm
on emp
FOR EACH ROW
BEGIN
IF (:NEW.JOB ='ANALYST')
THEN RAISE_APPLICATION_ERROR (-20010,
'Analyste ne peut pas avoir une commission');
END IF;
END;
/

64
create or replace trigger del_emp
before delete or update or insert
on emp
for each row
begin
if deleting then
insert into EMP_ARCHIVE
values(:old.empno,:old.ENAME,:old.JOB,:old.MGR ,:old.HIREDATE
,:old.SAL ,:old.COMM ,:old.DEPTNO,sysdate,'delete',USER);
end if;
if updating then
insert into EMP_ARCHIVE
values(:old.empno,:old.ENAME,:old.JOB,:old.MGR ,:old.HIREDATE
,:old.SAL ,:old.COMM ,:old.DEPTNO,sysdate,'update',USER);
end if;
if inserting then
if (:new.deptno=9) then
raise_application_error(-20009,'erreur insertion');
end if;
end if;

end;

65
Désactivation ou réactivation d’un trigger de base de données :

ALTER TRIGGER trigger_name DISABLE | ENABLE

Désactivation ou réactivation de tous les triggers d’une table :

ALTER TRIGGER table_name DISABLE | ENABLE ALL TRIGGERS

Recompilation d’un trigger pour une table :

ALTER TRIGGER trigger_name COMPILE

Pour supprimer un trigger de la base de données:

DROP TRIGGER trigger_name

66

Vous aimerez peut-être aussi