Vous êtes sur la page 1sur 84

Conception de bases de donnes

Technologie
Oracle :
Extensions
procdurales
SQL
http://bdd.crzt.fr

STPHANE CROZAT

Paternit - Partage des Conditions Initiales l'Identique :


http://creativecommons.org/licenses/by-sa/2.0/fr/

25 juillet 2014

Table des
matires
I - Thorie : Oracle

A. Introduction Oracle.....................................................................................7
1. Exemple complet BD "Gestion des intervenants"...................................................................7
2. Prsentation...................................................................................................................12
3. Particularits LDD............................................................................................................13
4. Dictionnaire de donnes...................................................................................................14
5. Les squences................................................................................................................15
6. Particularits LMD...........................................................................................................16
7. Fonctions SQL connatre................................................................................................17
8. Fonctions de traitement des dates.....................................................................................19
9. SQL*Plus.......................................................................................................................20
10. Accs inter-schmas......................................................................................................21
11. Fentrage des donnes..................................................................................................22

B. Le langage procdural PL/SQL......................................................................23


1. Prsentation du PL/SQL....................................................................................................23
2. Structure d'un bloc PL/SQL...............................................................................................23
3. Variables........................................................................................................................24
4. Affichage l'cran...........................................................................................................25
5. Structures de contrle.....................................................................................................25
6. Blocs PL/SQL : Procdure, fonction, bloc anonyme...............................................................25
7. Affectation par une requte SELECT INTO...........................................................................27
8. Exercice.........................................................................................................................28
9. Curseurs PL/SQL.............................................................................................................28
10. Exercice.......................................................................................................................30
11. Gestion d'exception.......................................................................................................30
12. Dure de tournage d'un film...........................................................................................31

C. Les triggers................................................................................................32
1.
2.
3.
4.

Principes des triggers.......................................................................................................32


Manipulation des anciennes et nouvelles valeurs dans les triggers.........................................34
Prdicats d'vnement au sein des triggers........................................................................35
Exercice.........................................................................................................................36

D. Prise en main de Oracle SQL Developer.........................................................36


1.
2.
3.
4.
5.
6.

Installation de SQL Developer...........................................................................................36


Connexion avec SQL Developer.........................................................................................36
Naviguer dans le catalogue de SQL Developer.....................................................................37
Excuter des requtes SQL avec SQL Developer..................................................................38
crire du PL/SQL avec SQL Developer................................................................................40
Excution de fichiers SQL.................................................................................................42

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

II - Pratique : SQL sous Oracle

43

A. Migration d'une base Access vers Oracle........................................................43


B. Squence...................................................................................................46
C. Extension Mdiathque................................................................................47
D. Transactions...............................................................................................47
E. Questions avances en SQL..........................................................................48
F. Maintenance de la base................................................................................49
G. Vue...........................................................................................................49

III - Pratique : PL/SQL sous Oracle

51

A. Fonctions stockes......................................................................................51
B. Curseurs....................................................................................................52
C. Triggers.....................................................................................................53

IV - Application : Oracle

55

A. Dictionnaire de donnes...............................................................................55
B. SQL sous Oracle..........................................................................................56

V - Test : Oracle

59

VI - Questions-rponses sur Oracle

63

VII - En rsum : Oracle

65

VIII - Bibliographie commente sur Oracle

67

Questions de synthse

69

Solution des exercices

73

Solution des exercices

85

Signification des abrviations

89

Bibliographie

91

Webographie

93

Index

95

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

I-

Thorie : Oracle

Introduction Oracle

Le langage procdural PL/SQL

24

Les triggers

35

Prise en main de Oracle SQL Developer

39

A. Introduction Oracle
Objectifs
Utiliser un SGBD professionnel largement rpandu
Exprimenter l'usage du langage SQL
Savoir crer et interroger une base de donnes sous
Oracle
Connatre les commandes de base de SQL*Plus
Savoir utiliser le dictionnaire de donnes

1. Exemple complet BD "Gestion des intervenants"


Exemple

: Modle conceptuel

MCD "Cours et Intervenants"

Exemple
1
2

: Schma relationnel

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

Thorie : Oracle

Exemple
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

CREATE TABLE tIntervenant (


pknom varchar2(20) PRIMARY KEY,
prenom varchar2(20) NOT NULL,
poste number(4)
);
CREATE TABLE tCours (
pkannee number(4) check (pkannee>2000 and pkannee<2100),
pknum number(2),
titre varchar2(50),
type char(2) CHECK (type='C' or type='TD' or type='TP') NOT NULL,
fkintervenant varchar2(20) REFERENCES tIntervenant(pknom) NOT NULL,
debut date,
fin date,
PRIMARY KEY(pkannee, pknum)
);

Exemple
1
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14

: Cration des tables

: Utilisation du catalogue

SELECT table_name FROM user_tables;


DESCRIBE tCours;
TABLE_NAME
-----------------------------TINTERVENANT
TCOURS
Name
------------PKANNEE
PKNUM
TITRE
TYPE
FKINTERVENANT
DEBUT
FIN

Exemple

Null
-------NOT NULL
NOT NULL

Type
-----------NUMBER(4)
NUMBER(2)
VARCHAR2(50)
NOT NULL CHAR(2)
NOT NULL VARCHAR2(20)
DATE
DATE

: Cration d'une squence

1
2
3

CREATE SEQUENCE tCoursSeq;

1
2
3

SEQUENCE_NAME
-----------------------TCOURSSEQ

SELECT sequence_name FROM user_sequences;

Exemple
1
2
3
4
5

: Initialisation des donnes

INSERT INTO tIntervenant (pknom, prenom, poste)


VALUES ('CROZAT', 'Stphane', '4287');
INSERT INTO tCours (pkannee, pknum, titre, type, debut,
fkintervenant)
VALUES ('2003', tCoursSeq.NEXTVAL, 'Introduction','C', '01-JAN2001', 'CROZAT');

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle
7
8
9
10
1
2
3
4

INSERT INTO tCours (pkannee, pknum, titre, type, debut,


fkintervenant)
VALUES ('2003', tCoursSeq.NEXTVAL, 'Modlisation','TD', '02-JAN2001', 'CROZAT');
SELECT pknum, pkannee, titre FROM tCours;
PKNUM PKANNEE TITRE
----- ------- ----------------1
2003 Introduction
2
2003 Modlisation

Exemple

: Question avec concatnation

SELECT trim(prenom) || ' ' || trim(pknom) || ' (' || trim(poste) ||


')' FROM tIntervenant;

1
2

TRIM(PRENOM)||''||TRIM(PKNOM)||'('||TRIM(POSTE)||')'

----------------------------------------------------------------------------------STEPHANE CROZAT (4287)

Exemple

: Question avec CASE

1
2
3
4
5
6
7

SELECT pknum,
CASE
WHEN type='C' THEN 'Cours'
WHEN type='TD' THEN 'Travaux dirigs'
END AS type_label,
debut
FROM tCours

1
2
3
4

PKNUM
----1
2

Exemple

TYPE_LABEL
--------------Cours
Travaux dirigs

DEBUT
--------01-JAN-01
02-JAN-01

: Question avec date

SELECT pknum, TO_CHAR(debut, 'fmday') FROM tcours;

1
2
3
4

PKNUM
----1
2

Exemple
1
2

TO_CHAR(DEBUT,'FMDAY')
---------------------monday
tuesday

: Insert avec date

INSERT INTO tCours (pkannee, pknum, titre, type, debut,


fkintervenant)
VALUES ('2003', tCoursSeq.NEXTVAL, 'Relationnel','C', TO_DATE('0801-2001','DD-MM-YYYY'), 'CROZAT');

3
4

SELECT debut FROM tCours;

DEBUT

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

Thorie : Oracle
2
3
4
5

--------01-JAN-01
02-JAN-01
08-JAN-01

Exemple
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4

CREATE OR REPLACE FUNCTION fIntervient (pIntervenant varchar2)


RETURN varchar2
IS
vNbInterventions number;
BEGIN
SELECT Count(fkintervenant) INTO vNbInterventions
FROM tCours
WHERE fkintervenant=pIntervenant;
IF vNbInterventions > 0 THEN
RETURN 'OUI';
ELSE
RETURN 'NON';
END IF;
END;
/
INSERT INTO tIntervenant(pknom, prenom) VALUES ('JOUGLET',
'Antoine');
SELECT pknom, fIntervient(pknom) AS I FROM tIntervenant;
PKNOM
-------------------CROZAT
JOUGLET

Exemple
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

10

: Fonction et affectation par une requte

I
-----OUI
NON

: Curseur

CREATE OR REPLACE PROCEDURE pAfficheIntervenants1


IS
CURSOR cIntervenants IS
SELECT pknom, prenom FROM tIntervenant;
vNom tIntervenant.pknom%TYPE;
vPrenom tIntervenant.prenom%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('** Liste des intervenants 1 **');
OPEN cIntervenants;
LOOP
FETCH cIntervenants INTO vNom, vPrenom;
EXIT WHEN cIntervenants%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('-' || INITCAP(TRIM(vPrenom)) || ' ' ||
INITCAP(TRIM(vNom)));
END LOOP;
END;
/
CREATE OR REPLACE PROCEDURE pAfficheIntervenants2
IS
CURSOR cIntervenants IS
SELECT pknom, prenom FROM tIntervenant;
BEGIN
DBMS_OUTPUT.PUT_LINE('** Liste des intervenants 2 **');
FOR i IN cIntervenants LOOP
DBMS_OUTPUT.PUT_LINE('-' || INITCAP(TRIM(i.prenom)) || ' ' ||
INITCAP(TRIM(i.pknom)));
END LOOP;

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle
27
28
29
30
31
32
33
34
35
36
1
2
3
4
5
6
7

END;
/
SET SERVEROUTPUT ON;
BEGIN
pAfficheIntervenants1;
DBMS_OUTPUT.PUT_LINE('');
pAfficheIntervenants2;
END;
/
** Liste des intervenants 1 **
-Stphane Crozat
-Antoine Jouglet
** Liste des intervenants 2 **
-Stphane Crozat
-Antoine Jouglet

Exemple
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6

CREATE OR REPLACE PROCEDURE pInsertIntervenant (pNom varchar2,


pPrenom varchar2)
IS
BEGIN
INSERT INTO tIntervenant (pknom, prenom)
VALUES (pNom, pPrenom);
EXCEPTION
WHEN DUP_VAL_ON_INDEX then
DBMS_OUTPUT.PUT_LINE('Intervenant dj existant : ' || pNom);
WHEN OTHERS THEN
RAISE;
END;
/
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE('*** Programme indpendant ***');
pInsertIntervenant('JOUGLET', 'Antoine');
pInsertIntervenant('VINCENT', 'Antoine');
pAfficheIntervenants;
END;
/
*** Programme indpendant ***
Intervenant dj existant : JOUGLET
** Liste des intervenants 1 **
-Stphane Crozat
-Antoine Jouglet
-Antoine Vincent

Exemple
1
2
3
4
5
6
7
8
9

: Gestion d'exception

: Trigger de calcul de valeur drive

CREATE OR REPLACE TRIGGER trCours


BEFORE INSERT OR UPDATE OF debut ON tCours
FOR EACH ROW
BEGIN
:new.fin := :new.debut+5;
END;
/
UPDATE tCours

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

11

Thorie : Oracle
10
11
12
13
14
15
16
1
2
3
4
5
6

SET debut=TO_DATE('15-01-2001','DD-MM-YYYY')
WHERE pknum=3;
INSERT INTO tCours (pkannee, pknum, titre, type, fkIntervenant,
debut)
VALUES ('2003', tCoursSeq.NEXTVAL, 'SQL', 'C', 'CROZAT', TO_DATE('2201-2001','DD-MM-YYYY'));
SELECT pknum, debut, fin FROM tCours;
PKNUM
----1
2
3
4

Exemple
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

DEBUT
--------01-JAN-01
02-JAN-01
15-JAN-01
22-JAN-01

FIN
---------

20-JAN-01
27-JAN-01

: Trigger d'archivage de donnes

CREATE TABLE tIntervenantSav (


pknom varchar2(20) PRIMARY KEY,
prenom varchar2(20) NOT NULL
);
CREATE OR REPLACE TRIGGER trIntervenant
BEFORE DELETE OR INSERT ON tIntervenant
FOR EACH ROW
BEGIN
IF DELETING THEN
INSERT INTO tIntervenantSav VALUES (:old.pknom, :old.prenom);
ELSIF INSERTING THEN
DELETE FROM tIntervenantSav WHERE pknom = :new.pknom;
END IF;
END;
/
DELETE FROM tCours;
DELETE FROM tIntervenant;
SELECT * FROM tIntervenantSav;

1
2
3
4
5

PKNOM
-------------------CROZAT
JOUGLET
VINCENT

1
2
3
4

INSERT INTO tIntervenant (pknom, prenom, poste)


VALUES ('CROZAT', 'Stphane', '4287');

1
2
3
4

PKNOM
-------------------JOUGLET
VINCENT

PRENOM
-------------------Stphane
Antoine
Antoine

SELECT * FROM tIntervenantSav;


PRENOM
-------------------Antoine
Antoine

2. Prsentation

12

Le premier SGBDR commercialis en 1979


Il occupe la premire place dans le march des SGBDR (avec IBM)

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

volutions du produit :
depuis la version 7, architecture client-serveur
depuis la version 8, le serveur est objet-relationnel
depuis la version 8i, intgration de couches applicatives Web et
multimdia
depuis la version 9i, intgration de types de donnes XML, extension des
couches Web et introduction de fonctions de datawarehousing et de
business intelligence
Version actuelle (depuis 2013) : 12
Il fonctionne sous Unix, Linux, Windows.
Site officiel en France : www.oracle.fr
Il est possible de tlcharger gratuitement Oracle des fins de
dveloppement
et
de
prototypage
:
http://otn.oracle.com/software/index.html

3. Particularits LDD
Type de donnes

NUMBER(e,d)
DATE
CHAR(l), VARCHAR2(lmax)
LONG, CLOB, BLOB, BFILE

Remarque
Il n'y a pas de type de donnes boolennes.

Remarque : varchar et varchar2

varchar et varchar2 se comportent exactement de la mme faon pour le


moment ;
mais Oracle prvoit d'utiliser diffremment varchar dans le futur.

Oracle recommande de ne pas utiliser varchar, mais d'utiliser varchar2.

Conseil : Pour entrer dans le dtail

Vous pouvez consulter Oracle : SQL [w_loria.fr/~roegel(1)], page 2 et 3,


pour avoir une description plus dtaille des types de donnes.
http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm

Exemple
1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple
1
2
3
4

: BD "Gestion des intervenants" : Schma relationnel

: BD "Gestion des intervenants" : Cration des tables

CREATE TABLE tIntervenant (


pknom varchar2(20) PRIMARY KEY,
prenom varchar2(20) NOT NULL,
poste number(4)

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

13

Thorie : Oracle
5
6
7
8
9
10
11
12
13
14
15
16

);
CREATE TABLE tCours (
pkannee number(4) check (pkannee>2000 and pkannee<2100),
pknum number(2),
titre varchar2(50),
type char(2) CHECK (type='C' or type='TD' or type='TP') NOT NULL,
fkintervenant varchar2(20) REFERENCES tIntervenant(pknom) NOT NULL,
debut date,
fin date,
PRIMARY KEY(pkannee, pknum)
);

4. Dictionnaire de donnes
Rappel
Le dictionnaire des donnes contient la description des objets crs et maintenus
par le serveur Oracle.

Syntaxe : Lister les objets appartenant l'utilisateur

SELECT
SELECT
SELECT
SELECT
...

*
*
*
*

FROM
FROM
FROM
FROM

user_tables;
user_sequences;
user_views;
user_procedures;

Syntaxe : Dcrire un objet

describe nom_objet

Complment

Afficher les diffrents types d'objets appartenant l'utilisateur :


SELECT object_type FROM user_objects;

Afficher la liste des objets appartenant l'utilisateur :


SELECT * FROM user_catalog;

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple
catalogue

14

: BD "Gestion des intervenants" : Utilisation du

1
2

SELECT table_name FROM user_tables;


DESCRIBE tCours;

1
2
3
4
5

TABLE_NAME
-----------------------------TINTERVENANT
TCOURS

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle
6
7
8
9
10
11
12
13
14

Name
------------PKANNEE
PKNUM
TITRE
TYPE
FKINTERVENANT
DEBUT
FIN

Null
-------NOT NULL
NOT NULL

Type
-----------NUMBER(4)
NUMBER(2)
VARCHAR2(50)
NOT NULL CHAR(2)
NOT NULL VARCHAR2(20)
DATE
DATE

5. Les squences
Dfinition : Squence
Les squences permettent de gnrer automatiquement des numros uniques (en
gnral pour crer une valeur de cl primaire artificielle).
Elles remplissent une fonction de compteur :

mmoriser une valeur

retourner la valeur

incrmenter la valeur

Remarque
Les squences sont des objets indpendants des tables.

Syntaxe : Cration de squence


1

CREATE SEQUENCE nom_sequence [START WITH x]

Syntaxe : Valeur d'une squence


1

nom_sequence.CURRVAL

Syntaxe : Incrment de squence


1

nom_sequence.NEXTVAL

Remarque : user_sequences
Table du catalogue o se trouvent les informations concernant les squences.

Remarque : START WITH


La clause START WITH de l'instruction CREATE SEQUENCE permet de dfinir la
premire valeur de la squence.

Conseil : Pour entrer dans le dtail


Vous pouvez consulter Oracle : SQL [w_loria.fr/~roegel(1)], page 7, pour avoir une
description plus dtaille de la syntaxe des squences et disposer d'exemples.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

15

Thorie : Oracle

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple
squence

: BD "Gestion des intervenants" : Cration d'une

1
2
3

CREATE SEQUENCE tCoursSeq;

1
2
3

SEQUENCE_NAME
-----------------------TCOURSSEQ

SELECT sequence_name FROM user_sequences;

Exemple
donnes
1
2
3
4
5
6
7
8
9
10
1
2
3
4

: BD "Gestion des intervenants" : Initialisation des

INSERT INTO tIntervenant (pknom, prenom, poste)


VALUES ('CROZAT', 'Stphane', '4287');
INSERT INTO tCours (pkannee, pknum, titre, type, debut,
fkintervenant)
VALUES ('2003', tCoursSeq.NEXTVAL, 'Introduction','C', '01-JAN2001', 'CROZAT');
INSERT INTO tCours (pkannee, pknum, titre, type, debut,
fkintervenant)
VALUES ('2003', tCoursSeq.NEXTVAL, 'Modlisation','TD', '02-JAN2001', 'CROZAT');
SELECT pknum, pkannee, titre FROM tCours;
PKNUM PKANNEE TITRE
----- ------- ----------------1
2003 Introduction
2
2003 Modlisation

6. Particularits LMD
Oprateur de concatnation
L'oprateur de concatnation s'crit ||.
Il permet de concatner des colonnes et/ou des chanes de caractres.
La colonne rsultante est une chane de caractre.
1

SELECT Attribut1 || '+' || Attribut2 AS "A1+A2" FROM ...

Valeurs Null
Les expressions mathmatiques contenant une valeur Null sont systmatiquement
values Null.
SELECT x+y FROM t renverra des valeurs Null si x ou y ont la valeur Null.

16

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

On peut utiliser la fonction NVL pour procder diffremment : par exemple


NVL(X,0) renvoie 0 si X vaut Null.

MINUS, UNION ALL, LEFT JOIN, AS...

L'opration relationnelle de diffrence s'crit MINUS (au lieu de EXCEPT en


SQL)
UNION ALL est une opration d'union qui ne supprime pas les doublons

LEFT JOIN peut s'crire grce l'oprateur "(+)" utilis dans la clause
WHERE : SELECT x,y FROM t1,t2 WHERE y(+)=x

Le AS servant pour le renommage de colonne est optionnel.

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple : BD "Gestion des intervenants" : Question avec


concatnation
1

SELECT trim(prenom) || ' ' || trim(pknom) || ' (' || trim(poste) ||


')' FROM tIntervenant;

1
2

TRIM(PRENOM)||''||TRIM(PKNOM)||'('||TRIM(POSTE)||')'

----------------------------------------------------------------------------------STEPHANE CROZAT (4287)

7. Fonctions SQL connatre


Rappel
Par opposition aux fonctions de calcul SQL qui s'appliquent sur toute la table pour
raliser des agrgats (en ne renvoyant qu'une seule valeur par regroupement), les
fonctions "mono-ligne" sont des fonctions au sens classique, qui s'appliquent une
ou plusieurs valeurs et renvoient une valeur en retour.
Les fonctions "mono-ligne" :

Manipulent des lments de donnes

Acceptent des arguments en entre et retournent des valeurs en sortie

Agissent sur chaque ligne

Retournent un seul rsultat par ligne

Peuvent modifier les types de donnes

Exemple

Traitement de chane
Concat, substr, length, insrt, lpad, trim
Lower, upper, initcap
Traitement de date
months_between, add_months, next_day, last_day,
SELECT sysdate FROM dual

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

17

Thorie : Oracle

Oprations mathmatiques sur les dates : SELECT sysdate + 10 FROM


dual

Traitement numrique
Round, Trunc
Floor, Ceil
Mod
Conversion
Conversion implicite
Conversion explicite : TO_DATE, TO_NUMBER, TO_CHAR
Gnrales
NVL (par exemple NVL(X,0) renvoie 0 si X vaut Null)
CASE WHEN condition1 THEN valeur1 WHEN condition2 THEN valeur2
ELSE valeur3 END
Imbrication de fonctions : F3(F2(F1(col,arg1),arg2),arg3)

Mthode
Les fonctions mono-ligne sont utilises pour :

Transformer les donnes

Formater des dates et des nombres pour l'affichage

Convertir des types de donnes de colonnes

...

Exemple

: Extraction de chane

La fonction substr(X, A, B) renvoie les B caractres partir du caractre A dans


la chane X.

Complment

Fonctions SQL1
Vous pouvez consulter Oracle : SQL [w_loria.fr/~roegel(1)], page 9 12,
pour avoir une description plus dtaille des fonctions disponibles sous
Oracle.

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple

: BD "Gestion des intervenants" : Question avec CASE

1
2
3
4
5
6
7

SELECT pknum,
CASE
WHEN type='C' THEN 'Cours'
WHEN type='TD' THEN 'Travaux dirigs'
END AS type_label,
debut
FROM tCours

1
2

PKNUM TYPE_LABEL
DEBUT
----- --------------- ---------

1 - http://docs.oracle.com/cd/B19188_01/doc/B15917/sqfunc.htm

18

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle
3
4

1 Cours
01-JAN-01
2 Travaux dirigs 02-JAN-01

8. Fonctions de traitement des dates


Syntaxe : Gestion des dates avec TO_DATE
La gestion des dates peut poser des problmes selon les formats paramtrs sur le
serveur Oracle (en gnral par dfaut le format est DD-MON-YY). La solution la plus
rigoureuse consiste utiliser la fonction de conversion TO_DATE.
1

to_date('20021130', 'YYYYMMDD') quivaut 30-NOV-2002.

Attention : TO_CHAR(date) et "fm" (format mask)


Les paramtres de type fm pour format mask (fmday, fmDay, fmDAY, fmMonth...)
permettent de supprimer les zros et espaces.
Ils sont privilgier en gnral :

TO_CHAR(date,'day') retourne 'saturday___' (avec des espaces la fin)

TO_CHAR(date,'fmday') retourne 'saturday'

Exemple

: BD "Gestion des intervenants" : Question avec date

SELECT pknum, TO_CHAR(debut, 'fmday') FROM tcours;

1
2
3
4

PKNUM
----1
2

Exemple
1
2

TO_CHAR(DEBUT,'FMDAY')
---------------------monday
tuesday

: BD "Gestion des intervenants" : Insert avec date

INSERT INTO tCours (pkannee, pknum, titre, type, debut,


fkintervenant)
VALUES ('2003', tCoursSeq.NEXTVAL, 'Relationnel','C', TO_DATE('0801-2001','DD-MM-YYYY'), 'CROZAT');

3
4

SELECT debut FROM tCours;

1
2
3
4
5

DEBUT
--------01-JAN-01
02-JAN-01
08-JAN-01

Complment

2
3
4
5
6

TO_CHAR(date)2 ; TO_CHAR(date)3
TO_CHAR(number)4
TO_DATE(char)5 ; TO_DATE(char)6

http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions180.htm
http://www.techonthenet.com/oracle/functions/to_char.php
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions181.htm
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions183.htm
http://www.techonthenet.com/oracle/functions/to_date.php

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

19

Thorie : Oracle

Formatage7

9. SQL*Plus
Dfinition : SQL*Plus

SQL*Plus est un client Oracle basique en mode texte, qui n'est plus vraiment
utilis (on utilise Oracle SQL Developer la place).
SQL*Plus dsigne aussi un langage interne Oracle destiner grer la
prsentation des rsultats de requtes en mode texte (tats textuels).

Complment

: SQL*Plus dans SQL Developer

Oracle SQL Developer utilise galement SQL*Plus mais ne supporte pas toutes les
fonctions.
http://www.oracle.com/technetwork/developer-tools/sql-developer/sql-worksheetcommands-097146.html

Mthode

: Usages

Le paramtrage de la prsentation des rsultats de requte est utile au


dveloppeur pour avoir des retours lisibles dans son terminal d'excution.
Il peut aussi servir des parties applicatives comme le formatage pour un
export CSV.
...

Attention
SQL*PLus ne travaille ni sur le contenu ni sur la structure, uniquement sur la
prsentation.

a) Variables d'environnement
Syntaxe
SQL*Plus permet de fixer la valeur de variables d'environnement avec la
commande :
1

SET param valeur

Ces paramtres peuvent tre lus avec la commande :


1

SHOW param

Exemple
1

SET heading off

Permet de dsactiver l'affichage des enttes de colonne dans le rsultat affich.

Complment
http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12040.htm

7 - http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm

20

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

b) Fichiers d'entre et de sortie


Syntaxe : Excuter un fichier
Pour excuter un fichier contenant des commandes SQL ou SQL*Plus :
1

@path/filename

Syntaxe : Sortie dans un fichier


Pour enregistrer les rsultats d'une excution de requtes dans un fichier :
1
2
3

SPOOL path/filename
-- requtes dont on veut rcuprer les rsultats dans le fichier
SPOOL OFF

Complment
Cration d'un fichier CSV avec SQL*Plus (cf. Cration d'un fichier CSV avec
SQL*Plus)

c) Formattage d'une colonne de requte


Syntaxe
1

COLUMN nom_colonne FORMAT format

Largeur de la colonne : An
Chiffre (avec ou sans zro gauche) : 9 / 0
Symboles montaires : $ / L
Sparateurs de virgule et de milliers : . / ,
...

Exemple
1
2
3

COLUMN ename FORMAT A15


COLUMN sal FORMAT $99,990.00
COLUMN mgr FORMAT 999999999

10. Accs inter-schmas


Un schma Oracle correspond au sein d'une base de donnes (instance Oracle) un
espace isol comportant toutes les tables appartenant d'un utilisateur du SGBD.
Ainsi chaque utilisateur possde un schma.
Pour simplifier on pourrait plutt dire qu'une base Oracle est en fait une collection
de BD et qu'un schma est une BD.
Lorsqu'un utilisateur se connecte il se connecte gnralement dans son propre
schma. Il lui est nanmoins possible de travailler sur les tables d'autres schmas,
condition d'avoir les droits associs bien entendu.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

21

Thorie : Oracle

Instance Oracle
sch1

tab2

tab1
tab3

sch2

sch3

Organisation en schmas d'une instance Oracle

Syntaxe : Lecture des donnes d'une table d'un autre schma


Il suffit de prfixer les noms des tables de leur nom de schma.
1

SELECT * FROM schema.table;

11. Fentrage des donnes


Syntaxe : Rownum
1
2

SELECT ... FROM ... WHERE rownum<=N;


-- avec N le nombre de lignes dsires.

Rownum
La restriction ROWNUM <= N dans la clause WHERE permet filtrer les N premires
lignes de la table.

Remarque
rownum est une pseudo colonne qu'il est bien entendu possible de projeter : SELECT
rownum FROM ...

Syntaxe : Utilisation avance


1
2
3

SELECT a1, ..., aN FROM


(SELECT a1, ..., aN, rownum AS rnum FROM t)
WHERE rnum BETWEEN n1 AND n2

Cette syntaxe permet de slectionner une fentre sur les donnes et pas seulement
les N premires lignes.

Mthode

: Exploration de donnes massives

Lorsque l'on est en prsence de gros volumes de donnes, et que l'on veut se faire
une ide du contenu de ces donnes, il n'est pas souhaitable de faire un simple
SELECT *. En il serait trop long de rapatrier les dizaines de milliers de lignes et de
plus cela serait inutile puisque seules quelques unes seraient effectivement lues.
L'usage de rownum permet de s'intresser des fentres de donnes
reprsentatives, pour se faire une ide gnrale.

22

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

B. Le langage procdural PL/SQL


Objectifs
Connatre les bases du PL/SQL sous Oracle.
Savoir crer et excuter des procdures et fonctions
PL/SQL.
Savoir utiliser les curseurs.

1. Prsentation du PL/SQL
Description

Langage de programmation d'Oracle.


Permet une manipulation procdurale de requtes SQL.

Avantages

Intgration
Il est possible d'crire des fonctions complexes de manipulation de donnes
sans recourir un langage externe.
Amlioration des performances
Le code PL/SQL est trs proche du moteur Oracle. De plus pour le code
stock, les requtes qu'il manipule sont pr-compiles, et donc son
excution est optimise.

2. Structure d'un bloc PL/SQL


Syntaxe
1
2
3
4
5
6
7
8

[Declare]
Variables, curseurs, etc.
Begin
Instructions SQL et PL/SQL
[Exception]
Gestion d'erreur.
End ;
/

Attention : /
Un bloc PL/SQL est termin par un ; comme une instruction SQL.
Par ailleurs, dans les environnements d'excution Oracle (comme SQL*Plus, SQL
Developer...), il est ncessaire de sparer les blocs par un "/" (sur une nouvelle
ligne).
Une bonne habitude est donc de terminer les bloc PL/SQL par des "/".

Complment
http://stackoverflow.com/questions/3024418/two-plsql-statements-with-beginand-end-run-fine-seperately-but-not-together

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

23

Thorie : Oracle

3. Variables
Attention
En PL/SQL les variables doivent tre dclares avant le BEGIN (aprs DECLARE
pour les blocs anonymes et IS pour les fonctions et procdures).

Types de variables

Scalaires
VARCHAR, DATE, CHAR, LONG, BOOLEAN, INTEGER
RECORD
Dclaration d'un type RECORD : TYPE nom_type IS RECORD (dclaration de
proprits);
Dclaration d'une variable enregistrement de ce type : nom_variable
nom_type;
Curseurs
Permettent de manipuler des rsultats de requte.

Syntaxe : Dclaration des variables


1

identifiant [CONSTANT] type [NOT NULL] [:= valeur];

Exemple
1
2
3
4
5
6
7

: Dclaration des variables

DECLARE
v_deptno NUMBER(2) NOT NULL := 10;
v_hiredate DATE;
v_location VARCHAR2(13) := 'Atlanta';
c_comm CONSTANT NUMBER := 1400;
BEGIN
...

Syntaxe : Affectation des variables


1

variable := valeur | variable

Exemple
1
2

: Affectation des variables

x:=10;
x:=y;

Conseil : Rfrence un type de colonne existant


On peut faire rfrence au type d'une colonne d'une table par la syntaxe suivante
en remplacement du type de donnes : nom_table.nom_colonne%TYPE.

Exemple
1

24

: Rfrence un type de colonne existant

vPersonne tEmploye.aNom%TYPE

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

4. Affichage l'cran
Syntaxe
1

SET SERVEROUTPUT ON

1
2
3

BEGIN
DBMS_OUTPUT.PUT_LINE ('Hello World');
END;

5. Structures de contrle
Syntaxe : Structure conditionnelle
1
2
3
4
5
6
7

IF THEN
instructions
ELSIF THEN
instructions
ELSE
instructions
END IF;

Syntaxe : Boucle FOR


1
2
3

FOR compteur IN [REVERSE] inf...sup LOOP


instructions
END LOOP;

Syntaxe : Boucle WHILE


1
2
3

WHILE condition LOOP


instructions
END LOOP;

Syntaxe : Boucle REPEAT


1
2
3
4

LOOP
instructions
EXIT [WHEN condition];
END;

6. Blocs PL/SQL : Procdure, fonction, bloc anonyme


Syntaxe : Procdure
1
2
3
4
5
6
7
8

CREATE OR REPLACE PROCEDURE nom_proc


IS
...
BEGIN
...
[EXCEPTION]
...
END ;

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

25

Thorie : Oracle

Exemple
1
2
3
4
5
6

: Procdure

CREATE OR REPLACE PROCEDURE pHello (who VARCHAR2)


IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello ' || who);
END;
/

Syntaxe : Fonction
1
2
3
4
5
6
7
8
9
10

FUNCTION nom_func
RETURN type_retourn
IS
...
BEGIN
...
RETURN valeur;
[EXCEPTION]
...
END ;

Exemple
1
2
3
4
5
6
7
8

: Fonction

CREATE OR REPLACE FUNCTION fDateDuJour RETURN date


IS
vDate date;
BEGIN
SELECT SYSDATE INTO vDate FROM DUAL;
RETURN vDate;
END;
/

Attention
Le type de retourn par une fonction ne doit pas spcifier de taille :

RETURN varchar

et non RETURN varchar(10)

http://docs.oracle.com/cd/B13789_01/server.101/b10759/statements_5009.htm

Syntaxe : Anonyme
1
2
3
4
5
6
7

[DECLARE]
...
BEGIN
...
[EXCEPTION]
...
END ;

Exemple
1
2
3
4

26

: Script anonyme

SET SERVEROUTPUT ON;


BEGIN
pHello('World');
DBMS_OUTPUT.PUT_LINE(fDateDuJour);

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle
5
6

END;
/

7. Affectation par une requte SELECT INTO


Syntaxe
1
2
3
4

SELECT proprit1, proprit2, ...


INTO variable_name1, variable_name2, ...
FROM relations
WHERE condition;

A condition que la requte ne renvoie qu'un tuple et qu'elle projette autant de


proprits de ce tuple que de variables rfrences dans la clause INTO.

Exemple
1
2
3
4
5
6
7
8
9
10

DECLARE
v_deptno dept.deptno%TYPE;
v_loc dept.loc%TYPE;
BEGIN
SELECT deptno, loc
INTO v_deptno, v_loc
FROM dept
WHERE dname = 'SALES';
...
END;

Remarque : Syntaxe %TYPE


Cette syntaxe est largement recommande pour l'affectation depuis une requte.

Remarque : Affectation d'une variable RECORD


Il est possible avec la clause INTO d'affecter des rsultats de requte plusieurs
colonnes dans une variable RECORD.

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple : BD "Gestion des intervenants" : Fonction et affectation


par une requte
1
2
3
4
5
6
7
8
9
10
11
12

CREATE OR REPLACE FUNCTION fIntervient (pIntervenant varchar2)


RETURN varchar2
IS
vNbInterventions number;
BEGIN
SELECT Count(fkintervenant) INTO vNbInterventions
FROM tCours
WHERE fkintervenant=pIntervenant;
IF vNbInterventions > 0 THEN
RETURN 'OUI';
ELSE

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

27

Thorie : Oracle
13
14
15
16
17
18
19
20
1
2
3
4

RETURN 'NON';
END IF;
END;
/
INSERT INTO tIntervenant(pknom, prenom) VALUES ('JOUGLET',
'Antoine');
SELECT pknom, fIntervient(pknom) AS I FROM tIntervenant;
PKNOM
-------------------CROZAT
JOUGLET

I
-----OUI
NON

8. Exercice
[Solution n1 p 85]

Soit la squence d'instructions suivante sous Oracle :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

CREATE TABLE t_personnes (


a_nom varchar(10),
a_prenom varchar(10)
);
INSERT INTO t_personnes
VALUES ('dupond', 'paul');
INSERT INTO t_personnes
VALUES ('dupond', 'pierre');
CREATE FUNCTION fCherche (p_nom varchar)
RETURN varchar
IS
TYPE r_personne IS RECORD
(nom varchar(10), prenom varchar(10));
v_personne r_personne;
BEGIN
SELECT a_nom, a_prenom
INTO v_personne
FROM t_personnes
WHERE a_nom=p_nom;
RETURN v_personne.nom;
EXCEPTION
WHEN OTHERS THEN
RETURN ('erreur');
END;

Que renvoie la fonction "fCherche" si on lui passe en paramtre la chane


'dupond' ?

9. Curseurs PL/SQL
Dfinition : Curseur
Un curseur est un pointeur sur un rsultat de requte.

28

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

Syntaxe : Syntaxe OPEN/FETCH


1
2
3
4
5
6
7
8
9
10
11
12
13

DECLARE
CURSOR c_moncurseur IS
SELECT prop1, prop2, ... FROM relations;
vProp1 relation1.prop1%TYPE;
vProp2 ...
BEGIN
OPEN c_moncurseur;
LOOP
FETCH c_moncurseur INTO vProp1, vProp2, ...;
EXIT WHEN c_moncurseur%NOTFOUND;
instructions
END LOOP;
END;

Remarque : Syntaxe FOR/IN


1
2
3
4
5
6
7
8

DECLARE
CURSOR c_moncurseur IS
SELECT prop1, prop2, ... FROM relations;
BEGIN
FOR c_montuple IN c_moncurseur LOOP
instructions
END LOOP;
END;

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple : BD "Gestion des intervenants" : Traitement de donnes


et curseur
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

CREATE OR REPLACE PROCEDURE pAfficheIntervenants1


IS
CURSOR cIntervenants IS
SELECT pknom, prenom FROM tIntervenant;
vNom tIntervenant.pknom%TYPE;
vPrenom tIntervenant.prenom%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('** Liste des intervenants 1 **');
OPEN cIntervenants;
LOOP
FETCH cIntervenants INTO vNom, vPrenom;
EXIT WHEN cIntervenants%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('-' || INITCAP(TRIM(vPrenom)) || ' ' ||
INITCAP(TRIM(vNom)));
END LOOP;
END;
/
CREATE OR REPLACE PROCEDURE pAfficheIntervenants2
IS
CURSOR cIntervenants IS
SELECT pknom, prenom FROM tIntervenant;
BEGIN
DBMS_OUTPUT.PUT_LINE('** Liste des intervenants 2 **');
FOR i IN cIntervenants LOOP

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

29

Thorie : Oracle
25
26
27
28
29
30
31
32
33
34
35
36
1
2
3
4
5
6
7

DBMS_OUTPUT.PUT_LINE('-' || INITCAP(TRIM(i.prenom)) || ' ' ||


INITCAP(TRIM(i.pknom)));
END LOOP;
END;
/
SET SERVEROUTPUT ON;
BEGIN
pAfficheIntervenants1;
DBMS_OUTPUT.PUT_LINE('');
pAfficheIntervenants2;
END;
/
** Liste des intervenants 1 **
-Stphane Crozat
-Antoine Jouglet
** Liste des intervenants 2 **
-Stphane Crozat
-Antoine Jouglet

10. Exercice
[Solution n2 p 85]

Quelles instructions SQL renvoient la mme valeur que la fonction PL/SQL sous
Oracle suivante :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

CREATE FUNCTION fTruc RETURN number


IS
CURSOR c IS SELECT a FROM t;
x number;
y number;
BEGIN
y:=0;
OPEN c;
LOOP
FETCH c INTO x;
EXIT WHEN c%NOTFOUND;
y:=y+x;
END LOOP;
RETURN y;
END;

SELECT a FROM t;
SELECT count(a) FROM t;
SELECT avg(a) FROM t;

11. Gestion d'exception


Qu'est-ce qu'une exception ?
Un identifiant PL/SQL, de type erreur, dclench pendant l'excution du bloc.

Comment est-elle dclenche ?

30

Implicitement, par une erreur Oracle (NO_DATAFOUND, INVALID_CURSOR,

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

TOO_MANY_ROWS, etc.)
Explicitement, par le programme (dfini par l'utilisateur) : commande
"RAISE nom_exception"
Par le dveloppeur : Raise_application_error( -20023 , 'message')

Comment la traiter ?

En interceptant les exceptions


En la propageant l'environnement appelant

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6

: BD "Gestion des intervenants" : Gestion d'exception

CREATE OR REPLACE PROCEDURE pInsertIntervenant (pNom varchar2,


pPrenom varchar2)
IS
BEGIN
INSERT INTO tIntervenant (pknom, prenom)
VALUES (pNom, pPrenom);
EXCEPTION
WHEN DUP_VAL_ON_INDEX then
DBMS_OUTPUT.PUT_LINE('Intervenant dj existant : ' || pNom);
WHEN OTHERS THEN
RAISE;
END;
/
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE('*** Programme indpendant ***');
pInsertIntervenant('JOUGLET', 'Antoine');
pInsertIntervenant('VINCENT', 'Antoine');
pAfficheIntervenants;
END;
/
*** Programme indpendant ***
Intervenant dj existant : JOUGLET
** Liste des intervenants 1 **
-Stphane Crozat
-Antoine Jouglet
-Antoine Vincent

12. Dure de tournage d'un film


[10 min]
Soit le modle UML de la relation Film ci-aprs.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

31

Thorie : Oracle

Film (mthode)
Soit la table Film implmente sous Oracle et correspondant au modle
relationnel :
1

Film(#isan:char(33),titre:varchar2,debut:date,fin:date)

Question 1
[Solution n1 p 73]

crire une fonction duree permettant de retourner un nombre entier de jours entre
deux dates passes en argument.
Indice :
On pourra utiliser la conversion des dates en Julian day, c'est dire le nombre
de jours depuis le 01/01/-4712.

to_char(d,'j') retourne le Julian day de la date d sous la forme d'une


chane de caractres.
Exemple : to_char( to_date('20000101','YYYYMMDD')) = '2451545'

to_number(to_char(d,'j'),'9999999') retourne le Julian day de la


date d sous la forme d'un entier de 7 chiffres.
Exemple :
to_number(to_char(
= 2451545

to_date('20000101','YYYYMMDD'),'99999999')

Question 2
[Solution n2 p 73]

Crer en SQL une vue vFilm affichant tous les attributs de Film, avec une colonne
supplmentaire affichant la dure.

C. Les triggers
Objectifs
Comprendre le fonctionnement vnementiel des triggers.
Savoir crer un trigger sous Oracle.

1. Principes des triggers


Dfinition : Trigger
Un trigger (ou dclencheur) est un bloc PL/SQL associ une table permettant de

32

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

dclencher une action avant ou aprs un INSERT, UPDATE ou DELETE sur cette
table.
Les triggers sont stocks dans la base.

A quoi servent les triggers ?

Ils permettent de renforcer l'intgrit des donnes (mais on prfrera des


contraintes "check", "unique" ou "foreign key" quand c'est possible).
Ils permettent d'auditer des actions sur une table.
Ils permettent de calculer des valeurs drives pour d'autres colonnes de la
table.
Ils constituent ainsi une des solutions pour l'implmentation des attributs
drivs.

Types de triggers
Il existe deux types de triggers :

Trigger sur ligne


le trigger est excut pour chaque ligne concerne par l'instruction insert,
update ou delete (option "for each row").

Trigger sur instruction


le trigger est excut une seule fois pour l'instruction insert, update ou
delete, mme si elle traite plusieurs lignes d'un coup.

Syntaxe : Trigger
1
2
3
4
5
6
7
8
9

CREATE [OR REPLACE] TRIGGER nom_trigger {BEFORE|AFTER}


[INSERT OR][UPDATE [OF nom_colonne] OR][DELETE]
ON nom_Table
[FOR EACH ROW [WHEN (condition)] ]
DECLARE
[variable declarations]
BEGIN
instructions
END;

Remarque : Avant ou aprs ?


En gnral les triggers sont de type "before", en particulier pour les triggers sur
ligne, c'est dire qu'ils s'excutent avant que l'action considre soit excute, ce
qui permet d'inflchir le rsultat de cette action. Alors qu'un trigger "after" ne
pourra plus modifier le tuple considr et agira seulement sur d'autres tuples.

Attention : Triggers multiples


Une mme table peut avoir plusieurs triggers, mais cela est viter en gnral,
pour des raisons de facilit de maintenance et de performance.

Attention : Exception
Si l'excution du trigger choue, l'action (insert, update ou delete dans la table) est
annule (et retourne une exception Oracle).

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

33

Thorie : Oracle

2. Manipulation des anciennes et nouvelles valeurs


dans les triggers
Pour les triggers de type "for each row", les colonnes de la ligne courante doivent
tre rfrences spcifiquement selon que l'on veut l' ancienne ou la nouvelle
valeur :

:old.nom_colonne

:new.nom_colonne

Fondamental
Il ne faut pas lire des donnes d'une table en cours de modification autrement que
par les accs ":old" et ":new".

Attention : Anciennes valeurs en lecture seule


Il n'est jamais possible de modifier une colonne ":old".

Attention : Valeurs en lecture seule aprs


Pour les trigger "after", il n'est plus possible de modifier les colonnes ":new".

Remarque : Valeurs nulles


Pour les triggers "on insert" les colonnes ":old" ont la valeur NULL.
Pour les triggers "on delete" les colonnes ":new" ont la valeur NULL.

Attention
Il ne faut pas modifier de donnes dans les colonnes des "primary key", "foreign
key", ou "unique key" d'une table.

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple : BD "Gestion des intervenants" : Trigger de calcul de


valeur drive
1
2
3
4
5
6
7
8
9
10
11
12
13
14

CREATE OR REPLACE TRIGGER trCours


BEFORE INSERT OR UPDATE OF debut ON tCours
FOR EACH ROW
BEGIN
:new.fin := :new.debut+5;
END;
/
UPDATE tCours
SET debut=TO_DATE('15-01-2001','DD-MM-YYYY')
WHERE pknum=3;
INSERT INTO tCours (pkannee, pknum, titre, type, fkIntervenant,
debut)
VALUES ('2003', tCoursSeq.NEXTVAL, 'SQL', 'C', 'CROZAT', TO_DATE('2201-2001','DD-MM-YYYY'));

15

34

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle
16
1
2
3
4
5
6

SELECT pknum, debut, fin FROM tCours;


PKNUM
----1
2
3
4

DEBUT
--------01-JAN-01
02-JAN-01
15-JAN-01
22-JAN-01

FIN
---------

20-JAN-01
27-JAN-01

3. Prdicats d'vnement au sein des triggers


INSERTING

DELETING

UPDATING

UPDATING(nom_colonne)
Prdicats pour savoir dans quel contexte d'appel du trigger on est, ce qui permet
dans un mme trigger de s'adapter aux diffrents cas de dclenchement.

Rappel : BD "Gestion des intervenants" : Schma relationnel


1
2

tIntervenant (#pknom, prenom, poste)


tCours (#pkannee, #pknum, titre, type, fkintervenant=>tIntervenant,
debut, \fin)

Exemple
donnes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

: BD "Gestion des intervenants" : Trigger d'archivage de

CREATE TABLE tIntervenantSav (


pknom varchar2(20) PRIMARY KEY,
prenom varchar2(20) NOT NULL
);
CREATE OR REPLACE TRIGGER trIntervenant
BEFORE DELETE OR INSERT ON tIntervenant
FOR EACH ROW
BEGIN
IF DELETING THEN
INSERT INTO tIntervenantSav VALUES (:old.pknom, :old.prenom);
ELSIF INSERTING THEN
DELETE FROM tIntervenantSav WHERE pknom = :new.pknom;
END IF;
END;
/
DELETE FROM tCours;
DELETE FROM tIntervenant;
SELECT * FROM tIntervenantSav;

1
2
3
4
5

PKNOM
-------------------CROZAT
JOUGLET
VINCENT

1
2
3
4

INSERT INTO tIntervenant (pknom, prenom, poste)


VALUES ('CROZAT', 'Stphane', '4287');

PRENOM
-------------------Stphane
Antoine
Antoine

SELECT * FROM tIntervenantSav;

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

35

Thorie : Oracle

1
2
3
4

PKNOM
-------------------JOUGLET
VINCENT

PRENOM
-------------------Antoine
Antoine

4. Exercice
[Solution n3 p 85]

Quelle valeur renvoie la dernire instruction de la liste ci-dessous, sous le SGBDR


Oracle :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

CREATE TABLE t (a integer, b integer);


CREATE TRIGGER trig_t
BEFORE UPDATE
ON t
FOR EACH ROW
BEGIN
:new.b := :old.a;
END;
INSERT INTO t (a, b) VALUES (1, 1);
UPDATE t SET a=a+1, b=b+1;
UPDATE t SET a=a+1, b=b+1;
SELECT sum(b) FROM

t;

D. Prise en main de Oracle SQL Developer


1. Installation de SQL Developer
Site Web
http://www.oracle.com/technology/products/database/sql_developer
(Tlchargement pour Windows, Mac et Linux)

Complment
Documentation en ligne disponible la mme adresse.

2. Connexion avec SQL Developer


Crer une connexion la base de donnes Oracle de l'UTC
1. Clic droit sur Connexions, puis Nouvelle connexion
2. Entrez vos paramtres :
Nom libre
Username / Password
Hte : sme-oracle.sme.utc
SID : nf26

36

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

Image 1 Fentre de connexion SQL Developer

3. Naviguer dans le catalogue de SQL Developer


L'espace de gauche permet de naviguer dans le catalogue de la base de donnes et
donc de visualiser les tables, vues, index, etc.

Image 2 Fentre principale SQL Developer

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

37

Thorie : Oracle

Attention
Pour rafrachir la vue de gauche (catalogue) aprs une requte LDD, il faut faire un
clic droit sur l'lment du catalogue (par exemple Tables aprs une cration de
table) puis slectionner Rgnrer.

4. Excuter des requtes SQL avec SQL Developer


L'espace de droite permet d'crire des requtes SQL (en haut) et de visualiser le
rsultat de l'excution (en bas). Appuyer sur le bouton Excuter un script
ou
faire F5 pour excuter les requtes saisies.

Image 3 SQL (script)

Remarque
Pour effacer les rsultats d'excution prcdents, cliquer sur Effacer

Excuter une seule requte au sein d'un script


Pour n'excuter qu'une seule requte parmi celle saisies dans la zone du haut, la
slectionner, puis cliquer sur Excuter un script ou faire F5.

38

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

Image 4 SQL (instruction par instruction)

Excuter une seule requte SELECT


Pour les requtes SELECT, SQL Developer propose un affichage sous forme de
tableau, plus lisible que l'affichage texte. Pour excuter une requte SELECT et
obtenir un tel affichage, cliquer sur Excuter l'instruction
ou faire F9.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

39

Thorie : Oracle

Image 5 SQL (une seule instruction SELECT)

Attention
Le bouton Excuter l'instruction n'affiche pas les erreurs d'excution ou les
confirmations de cration ou insertion (requtes CREATE, INSERT, UPDATE), il est
donc rserver aux requtes SELECT valides (si le rsultat n'est pas correct,
utiliser Excuter un script).

Conseil
Dans le doute utilisez toujours F5 et jamais F9.

5. crire du PL/SQL avec SQL Developer


Pour crer des blocs PL/SQL, procder comme pour le SQL, avec le bouton
Excuter un script.

40

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Thorie : Oracle

Image 6 PL/SQL (Fonction compile avec succs)

Attention : Traiter les erreurs de compilation


Pour voir les erreurs de compilation, il faut faire un clic droit sur le nom de la
fonction ou de la procdure (zone de gauche), puis choisir Compiler pour le
dbogage.
L'instruction show errors ne fonctionne pas.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

41

Thorie : Oracle

Image 7 PL/SQL (Fonction en erreur)

6. Excution de fichiers SQL


Mthode
Pour enregistrer un script SQL ou PL/SQL crit dans Oracle SQL Developer sous la
forme d'un fichier utiliser la fonction file > save as.

Mthode
Pour excuter un fichier SQL ou PL/SQL utiliser la commande @fichier.sql

Exemple
1
2
3

42

: script.sql

@file1.sql
@file2.sql
@file3.sql

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Pratique : SQL
sous Oracle
II -

II

Migration d'une base Access vers Oracle

48

Squence

51

Extension Mdiathque

51

Transactions

52

Questions avances en SQL

53

Maintenance de la base

54

Vue

54

Objectifs

Apprendre se servir d'Oracle


Approfondir SQL

Dans cette premire partie, vous allez aborder les aspects classiques des BD et du
SQL, sur le cas particulier d'Oracle.
Il est demand de prendre des notes au niveau de chaque question pose, afin de
garder la trace des ralisations.
Attention : Oracle est un systme transactionnel, il faut terminer chaque squence
de requtes par une instruction SQL "commit;".

A. Migration d'une base Access vers Oracle


Aprs un an de bons et loyaux services au sein de l'association "Objectifs", vous en
laissez la prsidence Marc. En effet, suite votre excellent travail de structuration
des activits de l'association dans une base Access, l'association des anciens lves
vous invite venir lui faire profiter de vos comptences, ce que vous avez accept
avec plaisir. Aprs une nouvelle anne, Marc vous demande de bien vouloir revenir
dans l'association "Objectifs" pour l'aider dans un projet ambitieux.
La base de donnes que vous aviez cre sous Access doit tre migre sous Oracle,
sur prconisation du service informatique.
Question 1
Prenez connaissance de la documentation (diagramme UML et code SQL de cration
et d'initialisation de la base de donnes), afin de prparer la migration de l'existant.
Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine
Vincent)

43

Pratique : SQL sous Oracle

Vrifiez que les donnes dont vous disposez sont cohrentes. Vrifier que le code
SQL LDD et LMD a t correctement adapt pour une implmentation sous Oracle.

Image 8 Modle UML de la base de donnes de gestion de projets


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

44

create table SPECIALITE (


intitule varchar(20),
constraint PK_SPECIALITE primary key (intitule)
);
create table MEMBRE (
prenom varchar(20),
nom varchar(20),
specialite varchar(20),
constraint PK_MEMBRE primary key (prenom),
constraint FK_MEMBRE_SPECIALITE foreign key (specialite) references
SPECIALITE(intitule)
);
create table PROJET (
num number,
nom varchar(20),
debut date,
fin date,
chefprojet varchar(20),
specialite varchar(20),
constraint PK_PROJET primary key (num),
constraint FK_PROJET_MEMBRE foreign key (chefprojet) references
MEMBRE(prenom),
constraint FK_PROJET_SPECIALITE foreign key (specialite) references
SPECIALITE(intitule)

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Pratique : SQL sous Oracle


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

);
create table TACHE (
num number,
projet number,
nom varchar(20),
debut date,
fin date,
constraint FK_TACHE_PROJET foreign key (projet) references
PROJET(num),
constraint PK_TACHE primary key (num, projet)
);
create table PARTENAIRE (
nom varchar(40),
description varchar(128),
constraint PK_PARTENAIRE primary key (nom)
);
create table PARTICIPE (
prenom varchar(20),
tache number,
projet number,
fonction varchar(60),
constraint FK_PARTICIPE_MEMBRE foreign key (prenom) references
MEMBRE(prenom),
constraint FK_PARTICIPE_TACHE foreign key (tache, projet)
references TACHE(num, projet),
constraint PK_PARTICIPE primary key (prenom, tache, projet)
);
create table ESTASSOCIE (
nom varchar(40), projet number,
role varchar(128),
constraint FK_ESTASSOCIE_PARTENAIRE foreign key (nom) references
PARTENAIRE(nom),
constraint FK_ESTASSOCIE_PROJET foreign key (projet) references
PROJET(num),
constraint PK_ASTASSOCIE primary key (nom, projet)
);
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT

INTO
INTO
INTO
INTO
INTO
INTO

Specialite
Specialite
Specialite
Specialite
Specialite
Specialite

INSERT
INSERT
INSERT
INSERT

INTO
INTO
INTO
INTO

Membre
Membre
Membre
Membre

VALUES
VALUES
VALUES
VALUES
VALUES
VALUES

VALUES
VALUES
VALUES
VALUES

('Ville');
('Universit');
('Sport');
('Entreprise');
('Culture');
('International');

('Nathalie', 'Dupont', 'Culture');


('Pierre', 'Perret', 'Sport');
('Alain', 'Durand', 'Culture');
('Julien', 'Dujnou', 'Universit');

INSERT INTO Projet VALUES (1, 'Comdie Musicale',


to_date('20020901','YYYYMMDD'), to_date('20021130','YYYYMMDD'),
'Nathalie', 'Culture');
INSERT INTO Projet VALUES (2, 'Science en fte',
to_date('20030301','YYYYMMDD'), to_date('20030630','YYYYMMDD'),
'Pierre', 'Ville');
INSERT INTO Projet VALUES (3, 'Nuit du Picolo',
to_date('20021101','YYYYMMDD'), to_date('20021130','YYYYMMDD'),
'Julien', 'Universit');
INSERT INTO Tache VALUES (1, 1,
to_date('20020901','YYYYMMDD'),
INSERT INTO Tache VALUES (2, 1,
to_date('20020901','YYYYMMDD'),
INSERT INTO Tache VALUES (3, 1,
to_date('20020901','YYYYMMDD'),

'Dossier financement',
to_date('20020930','YYYYMMDD'));
'Casting',
to_date('20020930','YYYYMMDD'));
'Script',
to_date('20020930','YYYYMMDD'));

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

45

Pratique : SQL sous Oracle


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

INSERT INTO Tache VALUES (4, 1,


to_date('20021001','YYYYMMDD'),
INSERT INTO Tache VALUES (5, 1,
to_date('20020901','YYYYMMDD'),
INSERT INTO Tache VALUES (6, 1,
to_date('20021101','YYYYMMDD'),
INSERT INTO Tache VALUES (7, 1,
to_date('20021115','YYYYMMDD'),
INSERT INTO Tache VALUES (1, 2,
to_date('20030315','YYYYMMDD'),

'Rptition',
to_date('20021130','YYYYMMDD'));
'Rservation salle',
to_date('20020915','YYYYMMDD'));
'Publicit',
to_date('20021115','YYYYMMDD'));
'Vente billets',
to_date('20021130','YYYYMMDD'));
'Programme',
to_date('20030415','YYYYMMDD'));

INSERT INTO Participe VALUES ('Alain', 1, 1, 'Prospection');


INSERT INTO Participe VALUES ('Nathalie', 1, 1, 'Rdaction');
INSERT INTO Partenaire (Nom)
INSERT INTO Partenaire (Nom)
INSERT INTO Partenaire (Nom)
INSERT INTO Partenaire (Nom,
de fabrication de bire');
INSERT INTO EstAssocie
INSERT INTO EstAssocie
INSERT INTO EstAssocie
INSERT INTO EstAssocie
'Publicitaire');
INSERT INTO EstAssocie
bires');

VALUES ('Mairie');
VALUES ('Ministre');
VALUES ('Association des commerants');
Description) VALUES ('1664', 'Entreprise

VALUES
VALUES
VALUES
VALUES

('Mairie', 1,
('Mairie', 2,
('Ministre',
('Association

'Financeur');
'Financeur');
2, 'Logistique');
des commerants', 1,

VALUES ('1664', 3, 'Rduction sur les

COMMIT;

Indice :
On notera que pour protger l'insertion des dates sous Oracle , la solution la plus
rigoureuse consiste utiliser la fonction de conversion TO_DATE. Par exemple :
INSERT INTO Projet VALUES (1, 'Comdie Musicale', to_date('20020901',
'YYYYMMDD'), to_date('20021130', 'YYYYMMDD'), 'Nathalie', 'Culture');
Question 2
Procdez la cration et l'initialisation de la base Oracle.

B. Squence
Marc a une formation solide en marketing. Dans son discours pour sa seconde
investiture la prsidence de l'association, il promet de donner un nouveau souffle
l'association suite des malentendus avec les supports financiers. Aprs
concertation des membres de l'association, Marc dcide alors de donner une
dimension commerciale aux activits de l'association dans le but d'autosubventionner ses projets.
Dans cette perspective, Marc lance un nouveau projet intitul "Mdiathque",
spcialis dans la vente de produits multimdia (CD-ROM, DVD, Vido, etc.)
distance (via Internet). Ce projet est compos de trois tches : "Marketing",
"Prospection" et "Service aprs-vente", et s'inscrit dans la spcialit "Commerce".
Question 1
[Solution n3 p 73]
Afin de profiter au mieux des fonctions proposes par Oracle, associez une
squence la table Projet pour grer l'itration automatique des numros de
projet.

Indice :

46

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Pratique : SQL sous Oracle

La clause START WITH de l'instruction CREATE SEQUENCE permet de dfinir


la premire valeur de la squence.
Question 2
[Solution n4 p 73]

crire et excuter les requtes LMD ncessaires la gestion du nouveau projet


"Mdiathque virtuelle", en utilisant la squence.

C. Extension Mdiathque
Submerg par la demande de la clientle, Marc fait appel vous pour tendre le
schma de la base de donnes de l'association afin d'automatiser les tches de
marketing (analyse des ventes, analyse des profils des clients) et commerciales
(facturation).
Cette extension doit inclure les nouvelles entits : client, produit, et facture.
Les rgles suivantes doivent tre respectes dans la conception du schma :

Une facture comporte un ou plusieurs produits.

Un produit peut paratre dans plusieurs factures.

Une facture est associe un seul client.

Un client peut tablir plusieurs factures.


Question 1
[Solution n5 p 74]

Faites le schma conceptuel de l'extension.


Question 2
[Solution n6 p 75]
Driver le modle relationnel.
Vous demandez un collgue de raliser pour vous les instructions de cration et
d'initialisation des tables, sur la base des donnes dont vous disposez.

Question 3
[Solution n7 p 75]

Vrifier que les scripts de cration et d'initialisation sont corrects, corrigez les sinon,
puis excutez les.

D. Transactions
Lors de la saisie d'une facture, le client peut changer d'avis : il n'a plus envie
d'acheter un article, il se rend compte qu'il n'a pas assez d'argent avec lui, etc.
Pour grer ces cas (et d'autres plus critiques, comme les cas de panne), on utilise
un mcanisme qui permet de valider ou d'annuler une transaction, c'est dire une
srie d'instructions SQL.
Question 1
Le client 1 souhaite acheter 1 exemplaire du produit 1, mais il change d'avis au
moment de valider.
Excutez le script SQL suivant et expliquez ce qui se passe.
1

select * from facture;

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

47

Pratique : SQL sous Oracle


2
3
4
5
6
7
8
9
10
11
12
13

select * from ligne_fact;


insert into FACTURE(num, client, date_etabli)
values( facture_seq.NEXTVAL, 1, to_date('18042002','DDMMYYYY' ) );
insert into LIGNE_FACT(facture, produit, qte)
values( facture_seq.CURRVAL, 1, 3 );
select * from facture;
select * from ligne_fact;
rollback;
select * from facture;
select * from ligne_fact;

Question 2
Cette fois la procdure est refaite et le client valide bien son achat.
Excutez ce second script SQL et expliquez ce qui se passe.
1
2
3
4
5
6
7
8
9
10
11
12
13

select * from facture;


select * from ligne_fact;
insert into FACTURE(num, client, date_etabli)
values( facture_seq.NEXTVAL, 1, to_date('18042002','DDMMYYYY' ) );
insert into LIGNE_FACT(facture, produit, qte)
values( facture_seq.CURRVAL, 1, 1);
select * from facture;
select * from ligne_fact;
commit;
select * from facture;
select * from ligne_fact;

E. Questions avances en SQL


A la fin de chaque anne, le service marketing tablit un ensemble d'tats qui
permettent d'analyser le profil de leurs clients (leurs prfrences, leur pouvoir
d'achat, etc.) et d'ajuster l'offre de l'association en consquence.
Question 1
[Solution n8 p 75]
crivez une requte SQL LMD pour calculer pour chaque produit, le nombre
d'articles vendus, tri par ordre dcroissant.

Indice :
Utilisez la fonction SUM applique la quantit sum(t.qte), la clause GROUP BY
pour faire les calculs par produit, et la clause ORDER BY pour le tri.
Question 2
[Solution n9 p 75]

Ecrivez une requte SQL LMD pour calculer les chiffres d'affaire par client, tris par
ordre dcroissant.
Indice :
Utilisez la fonction SUM applique au produit du prix et de la quantit
(sum(t1.prix*t2.qte)), la clause GROUP BY pour faire les calculs par client, et
la clause ORDER BY pour le tri.

48

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Pratique : SQL sous Oracle

Question 3
[Solution n10 p 76]

Ecrivez une requte SQL LMD pour calculer le montant moyen des factures pour
chaque client, tri par ordre croissant.
Indice :
Vous pouvez utiliser les sous-requtes dans la clause FROM pour traiter la
question en deux tapes.
Question 4
[Solution n11 p 76]

crivez deux requtes SQL LMD pour obtenir la liste des produits dont le prix est
maximal et dont le prix est minimal.
Indice :
Utilisez une sous-requte d'existence de type IN.

F. Maintenance de la base
Suite aux premiers usages, l'association se rend compte que le classement des
produits vendus par catgories (fiction, culture, musique, comdie, etc.) n'a pas t
prvu. Or l'association a besoin de connatre le nombre d'articles vendus par
catgorie.
Question 1
[Solution n12 p 76]
Ecrivez les requtes SQL LDD et LMD permettant de modifier la table "produit" et
ses donnes pour intgrer la proprit de catgorie.

Indice :
Utiliser ALTER pour modifier la dfinition de la table et UPDATE pour modifier les
donnes.
Question 2
[Solution n13 p 76]
Ecrivez la requte LMD permettant de rpondre la question que se pose
l'association (le nombre d'articles vendus par catgorie)

G. Vue
Le service aprs vente est instruit se comporter pragmatiquement vis vis
des clients, selon leur catgorie :

"VIP" si le chiffre d'affaire du client est suprieur 500 euros,

"client ordinaire" si son chiffre d'affaire est compris entre 50 et 500 euros,

et "client potentiel" si son chiffre d'affaire est infrieur 50 euros.


Le mcanisme de vue est frquemment utilis pour cacher la complexit d'un
schma de BD aux yeux d'oprateurs ncessitant un schma simple, ou pour
cacher des informations confidentielles aux oprateurs n'ayant pas le droit
d'accder des informations sensibles dans le schma.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

49

Pratique : SQL sous Oracle

Dans notre cas, les oprateurs du service aprs vente dsirent avoir la catgorie du
client au tlphone avec une instruction trs simple :
select * from Chiffre_Affaire where code_client=# ;
Question 1
[Solution n14 p 77]

crivez la requte SQL LMD qui permet de renvoyer la liste des clients (num, nom
et prnom) avec leur chiffre d'affaire et leur catgorie (VIP, Ordinaire ou Potentiel)
Indice :
Utiliser l'extension SQL CASE WHEN d'Oracle :
SELECT CASE WHEN ... THEN
'X' WHEN ... THEN 'Y' ELSE 'Z' END
FROM ...
Question 2
[Solution n15 p 77]
crivez la requte SQL LDD qui cre la vue "Chiffre_Affaire" permettant de
rpondre au besoin des oprateurs du service aprs vente.

Question 3
[Solution n16 p 77]

crire la requte SQL LMD qui renvoie la catgorie du client 1.


Indice :
Utilisez la vue dans la clause FROM de votre requte.

* *
*

Ce premier TP introductif fut l'occasion de manipuler Oracle partir d'lments en


majorit dj utiliss sous d'autres SGBD. Le second TP permettra quand lui
d'aller plus loin avec la manipulation du PL/SQL.

50

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Pratique : PL/SQL
sous Oracle
III -

III

Fonctions stockes

57

Curseurs

58

Triggers

59

Objectifs

Apprendre se servir d'Oracle


Apprendre programmer en PL/SQL
Exprimenter les dclencheurs

Vous allez dans cette seconde partie tudier des aspects de la gestion de BD plus
spcifiques Oracle, travers le langage PL/SQL.

A. Fonctions stockes
la fin de chaque anne, le fournisseur des produits du projet "Mdiathque
Virtuelle" demande l'association un inventaire sur les produits vendus. Cet
inventaire lui est envoy par e-mail pour analyse et traitement. L'information
demande est la suivante : donner pour chaque produit, sa dsignation, son prix
actuel, et une mention sur la demande :

demande "forte" si le nombre d'articles vendus dpasse 15,

demande "moyenne" si le nombre d'articles vendus est compris entre 11 et


15

et demande "faible" sinon


Question 1
[Solution n17 p 77]

Crer la table inventaire.


Question 2
[Solution n18 p 77]

crire une fonction stocke qui retourne la valeur de demande (forte, moyenne,
faible) en fonction d'un numro de produit.
Indices :
Pensez utiliser l'instruction show errors en fin de block PL/SQL pour avoir en
Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine
Vincent)

51

Pratique : PL/SQL sous Oracle

retour les ventuelles erreurs de complication.


Utilisez la trame suivante pour vous aider.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

CREATE OR REPLACE FUNCTION fDemande (num_produit in number) RETURN


varchar
IS
qte_vendue NUMBER;
BEGIN
SELECT ... INTO qte_vendue
FROM ...
WHERE ...
IF ... THEN
RETURN ('forte');
...
ELSE
...
END IF;
END fDemande;
/
SHOW ERRORS

Question 3
[Solution n19 p 78]

crire une requte SELECT qui utilise cette fonction pour prsenter la liste des
produits avec la demande.
Indice :
1

SELECT ..., f(...), ... FROM ... WHERE ...

Question 4
[Solution n20 p 78]
crire la requte INSERT permettant d'insrer les produits dans la table inventaire.

B. Curseurs
Afin de raffiner l'analyse du profil de chaque client, le service marketing souhaite
calculer pour chaque client le nombre de ses factures et son chiffre d'affaire total.
Question 1
[Solution n21 p 78]
crivez une procdure stocke qui prend en argument un numro de client, et deux
variables de type number, et qui retourne le nombre de factures et le chiffre
d'affaire dans ces deux variables.

Indice :
1
2

CREATE OR REPLACE PROCEDURE nb_fact(num_client IN NUMBER, nb OUT


NUMBER, ca OUT NUMBER)
...

Question 2
[Solution n22 p 79]
crivez un programme PL/SQL anonyme qui affiche pour le client numro 1 le
nombre de factures et le chiffre d'affaire.

Indices :

52

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Pratique : PL/SQL sous Oracle

Pensez excuter le "SET SERVEROUTPUT ON" avant l'excution de


"DBMS_OUTPUT.PUT_LINE".
Utlisez la syntaxe DECLARE ... BEGIN ... END pour dclarer un bloc PL/SQL
anonyme.
1
2
3
4
5
6
7
8
9

DECLARE
client NUMBER;
nb NUMBER;
ca NUMBER;
BEGIN
client:=1;
...
END;
/

Question 3
[Solution n23 p 79]

crivez un second programme PL/SQL qui affiche pour chaque client son nombre de
factures et son chiffre d'affaire
1
2
3
4
5
6
7

Client 1
10 / 152.23
-----------------Client 2
5 / 123.34
-----------------...

Indices :
Utiliser un curseur sur la table client :
1

CURSOR c_client IS SELECT num FROM client;

Utiliser le caractre de concatnation || pour afficher plusieurs informations sur


une mme ligne :
1

DBMS_OUTPUT.PUT_LINE('Client' || client.num);

C. Triggers
Un ensemble de rgles de gestion est dfini afin de grer le stock des produits du
projet "Mdiathque Virtuelle". La politique suivante a t admise :
1. aprs chaque vente, la quantit vendue est soustraite de la quantit
disponible indique dans une colonne de la table des produits,
2. si cette quantit (disponible) est infrieure un "seuil" alors insrer un
avertissement dans une table de journalisation : "Attention : rupture de
stock imminente", date du jour, numro de produit, nouveau stock aprs
mise jour.
Question 1
[Solution n24 p 79]

Crer un dclencheur permettant de mettre jour la quantit disponible dans la


table produit chaque insertion dans la table ligne facture (traitement du point 1).
Indices :

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

53

Pratique : PL/SQL sous Oracle

Il s'agit d'un trigger qui modifie une seconde table lorsqu'une premire est
modifie : utilisez un trigger "after"
1
2

CREATE TRIGGER TR_STOCK_AUDIT


AFTER INSERT ON ligne_fact

Il s'agit d'un trigger qui cherche faire une modification pour chaque insertion,
donc utilisez un trigger "for each row"
1

FOR EACH ROW

Utilisez une requte update pour effectuer la mise jour avec une condition sur
le numro de produit.
1
2
3

UPDATE ...
SET ...
WHERE num=:new.produit;

Question 2
[Solution n25 p 79]

Crer la table de journalisation.


Question 3
[Solution n26 p 79]

Modifiez votre dclencheur de telle faon qu'aprs la mise jour, il teste si le stock
est infrieur une valeur seuil de 5. Si le stock est infrieur ce seuil, alors il
devra insrer les informations adquates dans la table de journalisation (traitement
du point 2).

* *
*

Dcrivez le processus gnral de conception d'une base de donnes sous Oracle,


noncez des exemples pertinent d'utilisation du PL/SQL, en le positionnant par
rapport au SQL et aux langages applicatifs (comme PHP).
Appuyer vous sur ce que vous avez ralis pour montrer et argumenter.

54

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Application :
Oracle
IV -

IV

Dictionnaire de donnes

63

SQL sous Oracle

64

A. Dictionnaire de donnes
[45 min]
On souhaite crer la table EMPLOYEE de telle faon que le dictionnaire de donnes
graphique d'Oracle affiche le tableau ci-dessous.

Image 9 La table EMPLOYEE


Question 1
[Solution n27 p 80]

crivez le code SQL pour crer cette table sous Oracle.


Question 2
[Solution n28 p 80]

Vrifier que la table a bien t cre.


Indice :
Utiliser DESCRIBE.
Question 3
[Solution n29 p 80]

Modifier la table EMPLOYEE pour pouvoir allonger les noms de famille des employs
50 caractres. Vrifiez cette modification.
Question 4
[Solution n30 p 80]

Vrifiez l'existence de la table EMPLOYEE dans le dictionnaire de donnes.


Indice :
Faites une requte de slection sur la table du dictionnaire USER_TABLES.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

55

Application : Oracle

Question 5
[Solution n31 p 81]

Ajouter une contrainte PRIMARY KEY de niveau de table dans la table EMPLOYEE en
utilisant la colonne ID.
Question 6
[Solution n32 p 81]

Vrifier que la contrainte a bien t ajoute


USER_CONSTRAINTS ainsi que dans le mode graphique.

en

utilisant

la

table

Question 7
[Solution n33 p 81]
Rechercher les noms et types d'objets dans la vue USER_OBJECTS du dictionnaire
de donnes correspondant la table EMPLOYEE.

Question 8
[Solution n34 p 81]

Modifier la table EMPLOYEE. Ajouter une colonne SALARY de type NUMBER avec une
prcision 7.
Question 9
[Solution n35 p 81]

Renommez la table EMPLOYEE en EMPLOYEE2.


Question 10
[Solution n36 p 82]

Supprimez la table EMPLOYEE2.

B. SQL sous Oracle


[30 minutes]
Pour chacune des questions suivantes, crivez le code SQL permettant de rpondre
la question sous Oracle. On considre la table "emp" dcrite ci-dessous.
1

emp (ename, job, hiredate, sal)

Question 1
[Solution n37 p 82]

A partir de la table "emp", afficher le nom des employs ("ename") concatn avec
leur poste ("job") en les sparant par une virgule suivi d'une espace et donner
comme titre la colonne "EMPLOYE ET FONCTION"
Question 2
[Solution n38 p 82]

Afficher le nom et la date d'embauche ("hiredate") des employs embauchs entre


le 20 fvrier 1981, et 1 mai 1981. Classez le rsultat par date d'embauche.
Indice :
Attention l'utilisation du format "YY" qui pose des problme vis vis du
passage l'an 2000, prfrer le format "YYYY".
Question 3
[Solution n39 p 82]

Afficher le nom de tous les employs, dont le nom contient deux fois la lettre "L".

56

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Application : Oracle

Question 4
[Solution n40 p 82]

Afficher le nom, poste et salaire ("sal') de tous les personnes qui ont comme poste
'Clerk' ou 'Analyst' et dont le salaire est diffrent de $1000, $3000, ou $5000.
Question 5
[Solution n41 p 82]

Afficher le nom de chaque employ et calculer le nombre de mois qu'il a travaill


jusqu' ce jour (aprs l'avoir arrondi celui-ci la plus proche valeur entire).
Nommer la colonne MONTHS_WORKED.
Question 6
[Solution n42 p 83]

Ecrivez la requte qui affiche pour chaque employ le rsultat suivant :


"X" gagne "Y" par mois mais il veut "3 fois Y".
Nommer la colonne SALAIRES DE REVES.
Question 7
[Solution n43 p 83]

Afficher le salaire maximum, minimum, la somme des salaires et le salaire moyen


de tous les employs. Nommer les colonnes respectivement Maximum, Minimum,
Sum, and Average. Arrondissez les rsultats zro dcimales.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

57

V-

Test : Oracle

Exercice 1
[Solution n1 p 85]

Soit la squence d'instructions suivante sous Oracle :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

CREATE TABLE t_personnes (


a_nom varchar(10),
a_prenom varchar(10)
);
INSERT INTO t_personnes
VALUES ('dupond', 'paul');
INSERT INTO t_personnes
VALUES ('dupond', 'pierre');
CREATE FUNCTION fCherche (p_nom varchar)
RETURN varchar
IS
TYPE r_personne IS RECORD
(nom varchar(10), prenom varchar(10));
v_personne r_personne;
BEGIN
SELECT a_nom, a_prenom
INTO v_personne
FROM t_personnes
WHERE a_nom=p_nom;
RETURN v_personne.nom;
EXCEPTION
WHEN OTHERS THEN
RETURN ('erreur');
END;

Que renvoie la fonction "fCherche" si on lui passe en paramtre la chane


'dupond' ?

Exercice 2
[Solution n2 p 85]

Quelles instructions SQL renvoient la mme valeur que la fonction PL/SQL sous
Oracle suivante :
1
2
3
4
5
6

CREATE FUNCTION fTruc RETURN number


IS
CURSOR c IS SELECT a FROM t;
x number;
y number;
BEGIN

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

59

Test : Oracle
7
8
9
10
11
12
13
14
15

y:=0;
OPEN c;
LOOP
FETCH c INTO x;
EXIT WHEN c%NOTFOUND;
y:=y+x;
END LOOP;
RETURN y;
END;

SELECT a FROM t;
SELECT count(a) FROM t;
SELECT avg(a) FROM t;

Exercice 3
[Solution n3 p 85]

Quelle valeur renvoie la dernire instruction de la liste ci-dessous, sous le SGBDR


Oracle :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

CREATE TABLE t (a integer, b integer);


CREATE TRIGGER trig_t
BEFORE UPDATE
ON t
FOR EACH ROW
BEGIN
:new.b := :old.a;
END;
INSERT INTO t (a, b) VALUES (1, 1);
UPDATE t SET a=a+1, b=b+1;
UPDATE t SET a=a+1, b=b+1;
SELECT sum(b) FROM

t;

Exercice 4
[Solution n4 p 86]

Qu'affiche le code PL/SQL suivant excut sous Oracle ? (Ecrivez ERREUR en cas
d'erreur).
1
2
3
4
5
6
7
8
9
10
11
12
13
14

60

SET SERVEROUTPUT ON
CREATE OR REPLACE FUNCTION F RETURN NUMBER
IS
CURSOR vCs IS SELECT a FROM t1;
vRes NUMBER;
BEGIN
INSERT INTO t1 VALUES (10);
OPEN vCs;
FETCH vCs INTO vRes;
RETURN vRes;
END;
/

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Test : Oracle
15
16
17
18
19
20

CREATE TABLE t1 (a number);


INSERT INTO t1 VALUES (1);
BEGIN
DBMS_OUTPUT.PUT_LINE(F());
END;

Exercice 5 : Dclaration de variables


[Solution n5 p 86]

Exercice
La dclaration suivante est-elle valide ?
1
2

DECLARE
v_id
NUMBER(4);

Valide
Invalide

Exercice
La dclaration suivante est-elle valide ?
1
2

DECLARE
v_x, v_y, v_z

VARCHAR2(10);

Invalide
Valide

Exercice
La dclaration suivante est-elle valide ?
1
2

DECLARE
v_birthdate

DATE NOT NULL;

Invalide
Valide

Exercice
La dclaration suivante est-elle valide ?

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

61

Test : Oracle

1
2

DECLARE
v_in_stock

BOOLEAN := 1;

Invalide
Valide

Exercice 6 : Blocs PL/SQL


[Solution n6 p 86]

Exercice
Un trigger s'excute :
priodiquement
l'initialisation de la base de donnes
suite l'occurrence d'un vnement prcis
en invoquant la commande run
suite l'appel explicite du trigger

Exercice
Une procdure s'excute :
priodiquement
l'initialisation de la base de donnes
suite l'occurrence d'un vnement prcis
en invoquant la commande run
suite l'appel explicite de la procdure

62

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Questionsrponses sur
Oracle
VI -

VI

Comment avoir plus de prcision lorsque l'on a un message d'erreur


du type : type cr avec erreurs de compilation, ou procedure cre
avec erreurs de compilation ?
En ligne de commande
1
2
3
4
5

SHOW ERRORS [{ FUNCTION | PROCEDURE | PACKAGE |


PACKAGE BODY | TRIGGER | VIEW
| TYPE | TYPE BODY | DIMENSION
| JAVA SOURCE | JAVA CLASS } [schema.]name]

Dans l'OEM

Image 10 ULqrOra01img01.jpg

Quelle est la diffrence entre un trigger AFTER UPDATE et un trigger


BEFORE UPDATE ?
La diffrence est que dans un trigger BEFORE UPDATE vous avez le droit de
modifier les valeurs de mise jour ( travers les :new), tandis que sur un AFTER
UPDATE vous ne pouvez plus (la mise jour est termine).
On pourrait plus justement traduire le BEFORE UPDATE par "PENDANT LA MISE A
JOUR" et le AFTER UPDATE par "UNE FOIS LA MISE A JOUR TERMINEE".

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

63

Questions-rponses sur Oracle

Donc BEFORE UPDATE ne veut pas dire que le UPDATE se fera aprs le TRIGGER,
mais que le TRIGGER peut redfinir les valeurs :new de mise jour.
On notera que c'est la mme chose pour un BEFORE INSERT.

64

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

En rsum :
Oracle
VII -

VII

Oracle

SQL
Dfinition de la structure et du contenu de la BD.
SQL standard
Extensions
SQL*Plus
Environnement d'excution du SQL, de scripting simple et de formatage des
rsultats des requtes.
Ligne de commande
Fichiers de commande externes
tats textuels
PL/SQL
Programmation procdurales avance des accs la BD.
Blocs anonymes
Procdures et fonctions
Triggers

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

65

Bibliographie
commente sur
Oracle
VIII -

Complment

VIII

: Rfrences

Oracle 9i : Notions fondamentales [Abbey01]


Un aperu gnral des fonctionnalits de la version 9i d'Oracle.
Programmation SQL [Mata03]
Un aperu gnral du SQL sous Oracle 8, avec des exercices, des rfrences
(notamment sur les fonctions spcifiques Oracle)
Notes on the Oracle DBMS [w_stanford.edu]
Une srie de manuels en ligne dtaills et trs oprationnels sur l'utilisation
d'Oracle.
Oracle : SQL [w_loria.fr/~roegel(1)]
Une rfrence en ligne SQL sous Oracle.
Le langage procdural PL/SQL [w_loria.fr/~roegel(1)]
Une rfrence en ligne PL/SQL.
Computing Science 291/391 : Laboratory Manual [w_ualberta.ca]
Une rfrence gnrale en ligne sur Oracle 7 (On notera en particulier la rfrence
SQL sous Oracle http://ugweb.cs.ualberta.ca/~c391/manual/chapt6.html)

Complment

: Pour aller plus loin...

SQL2 SQL3, applications Oracle [Delmal01]


Le livre aborde de faon gnrale le SQL en intgrant les spcificits d'Oracle, en
particulier (pages 245-251) sur les clusters, avec de nombreux exemples d'usage.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

67

Questions de
synthse
A quoi servent les squences sous Oracle ?

L'environnement SQL*Plus fournit-il des instructions pour accder la BD ?

Citer quelques fonctions essentielles propres Oracle ?

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

69

Questions de synthse

A quoi sert un dictionnaire de donnes ?

Oracle, avec les langages SQL, SQL*Plus et PL/SQL est-il, votre avis, suffisant pour la
ralisation d'une application complte de base de donnes ?

Un langage procdural est-il toujours utile la ralisation d'une application d'exploitation


d'une BD ?

A quoi sert un curseur ?

70

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Questions de synthse

Quand peut on utiliser une affectation par une requte (SELECT INTO) et quand doit on
utiliser un curseur (CURSOR) ?

A quoi sert un trigger ? Donnez un exemple pertinent d'usage de trigger.

Un trigger permet-il d'amliorer le contrle des donnes ?

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

71

Solution des
exercices
> Solution n1 (exercice p. 32)
1
2
3
4
5

CREATE FUNCTION duree(debut date, fin date) RETURN integer


IS
BEGIN
RETURN to_number(to_char(fin,'j'),'99999999') to_number(to_char(debut,'j'),'99999999');
END;

> Solution n2 (exercice p. 32)


1
2
3

CREATE VIEW vFilm AS


SELECT isan, titre, debut, fin, duree(debut,fin)
FROM Film;

> Solution n3 (exercice p. 46)


1
2
3
4
5
6

CREATE SEQUENCE projet_seq


INCREMENT BY 1
START WITH 4
NOMAXVALUE
NOCYCLE
CACHE 10;

> Solution n4 (exercice p. 47)


1
2
3
4
5

6
7
8
9

INSERT INTO Specialite (intitule) values ('Commerce');


INSERT INTO Membre (prenom, nom, specialite) values ('Marc',
'Chardon', 'Commerce');
INSERT INTO Projet (num, nom, debut, fin, chefprojet, specialite)
values (projet_seq.NEXTVAL, 'Mediathque',
to_date('05102002','DDMMYYYY'), to_date('20012005','DDMMYYYY'),
'Marc', 'Commerce');
INSERT INTO Tache (num, projet, nom, debut, fin) values (1,
projet_seq.CURRVAL, 'Marketing', to_date('05102002','DDMMYYYY'),
to_date('10112002','DDMMYYYY') );
INSERT INTO Tache (num, projet, nom, debut, fin) values (2,
projet_seq.CURRVAL, 'Prospection', to_date('10112002','DDMMYYYY'),

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

73

Solution des exercices


to_date('20012005','DDMMYYYY') );
10
11
12
13

INSERT INTO Tache (num, projet, nom, debut, fin) values (3,
projet_seq.CURRVAL, 'SAV', to_date('10112002','DDMMYYYY'),
to_date('20012005','DDMMYYYY') );
COMMIT;

> Solution n5 (exercice p. 47)

Image 11 Schma UML de l'extension de la base

74

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Solution des exercices

Image 12 Schma E-A de l'extension de la base

> Solution n6 (exercice p. 47)


1
2
3
4

Client (#num:integer, nom:string, prenom:string, adresse:string,


date_nais:date, tel:string, sexe:char={'m','f'})
Produit (#num:integer, designation:string, prix:float, stock:integer)
Facture (#num:integer, date_etabli:date, client=>Client(num))
Ligne_Fact (#facture=>Facture(num), #produit=>Produit(num),
qte:integer)

> Solution n7 (exercice p. 47)


Les scripts sont corrects.

> Solution n8 (exercice p. 48)


1
2
3
4
5

select p.num, p.designation, sum(lf.qte) as nb


from produit p, ligne_fact lf
where lf.produit=p.num
group by p.num, p.designation
order by nb desc;

> Solution n9 (exercice p. 48)


1
2
3
4

select c.num, c.nom, c.prenom, sum(p.prix*lf.qte)


from client c, produit p, facture f, ligne_fact lf
where p.num=lf.produit
and lf.facture=f.num

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

75

Solution des exercices


5
6
7

and f.client=c.num
group by c.num, c.nom, c.prenom
order by sum(p.prix*lf.qte) DESC;

> Solution n10 (exercice p. 49)


1
2
3
4
5
6
7
8
9

select client, avg(montant) moy


from (
select c.num as client, f.num, sum(lf.qte*p.prix) as montant
from facture f, ligne_fact lf, client c, produit p
where lf.facture=f.num and lf.produit=p.num and f.client=c.num
group by c.num, f.num
)
group by client
order by moy;

> Solution n11 (exercice p. 49)


1
2
3

select distinct designation "PRIX MAX"


from produit
where prix in (select max(prix) from produit);

1
2
3

select distinct designation "PRIX MIN"


from produit
where prix in (select min(prix) from produit);

> Solution n12 (exercice p. 49)


1
1
2
3
4
5
6
7
8
9
10
11
12
13

alter table PRODUIT add (categorie varchar(50));


update PRODUIT
set categorie='fiction'
where num=1;
update PRODUIT
set categorie='fiction'
where num=2;
update PRODUIT
set categorie='musique'
where num=3;
commit;

> Solution n13 (exercice p. 49)


1
2
3
4

select p.categorie, sum(lf.qte)


from produit p, ligne_fact lf
where lf.produit=p.num
group by p.categorie;

> Solution n14 (exercice p. 50)

76

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Solution des exercices

1
2
3
4
5
6
7
8
9
10
11

SELECT c.num, c.nom, c.prenom, sum(p.prix*lf.qte) chiffre_affaire,


CASE
WHEN sum(p.prix*lf.qte)>500 THEN 'VIP'
WHEN sum(p.prix*lf.qte) BETWEEN 50 AND 500 THEN 'Ordinaire'
ELSE 'Potentiel'
END categorie
FROM client c, produit p, facture f, ligne_fact lf
WHERE p.num=lf.produit
AND lf.facture=f.num
AND f.client=c.num
GROUP BY c.num, c.nom, c.prenom;

> Solution n15 (exercice p. 50)


1
2
3
4
5
6
7
8
9
10
11
12

CREATE VIEW v_chiffre_affaire AS


SELECT c.num, c.nom, c.prenom, sum(p.prix*lf.qte) chiffre_affaire,
CASE
WHEN sum(p.prix*lf.qte)>500 THEN 'VIP'
WHEN sum(p.prix*lf.qte) BETWEEN 50 AND 500 THEN 'Ordinaire'
ELSE 'Potentiel'
END categorie
FROM client c, produit p, facture f, ligne_fact lf
WHERE p.num=lf.produit
AND lf.facture=f.num
AND f.client=c.num
GROUP BY c.num, c.nom, c.prenom;

> Solution n16 (exercice p. 50)


1

SELECT categorie FROM v_chiffre_affaire WHERE num=1;

> Solution n17 (exercice p. 51)


1
2
3
4
5
6
7

CREATE TABLE INVENTAIRE (


num NUMBER,
designation VARCHAR(128),
prix NUMBER,
demande VARCHAR(10),
CONSTRAINT PK_INVENTAIRE PRIMARY KEY (num)
);

> Solution n18 (exercice p. 51)


Solution avec un IF ... ELSIF ...
1
2
3
4
5
6
7
8
9

CREATE OR REPLACE FUNCTION fDemande (num_produit in number) RETURN


varchar
IS
qte_vendue NUMBER;
BEGIN
SELECT sum(lf.qte) INTO qte_vendue
FROM ligne_fact lf
WHERE lf.produit=num_produit;
IF (qte_vendue > 15) THEN
RETURN ('forte');

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

77

Solution des exercices


10
11
12
13
14
15
16
17

ELSIF (qte_vendue BETWEEN 11 AND 15) THEN


RETURN ('moyenne');
ELSE
RETURN('faible');
END IF;
END fDemande;
/
SHOW ERRORS

Solution alternative avec un CASE


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

CREATE OR REPLACE FUNCTION fDemande (num_produit in number) RETURN


varchar
IS
qte_vendue NUMBER;
BEGIN
SELECT sum(lf.qte) INTO qte_vendue
FROM ligne_fact lf
WHERE lf.produit=num_produit;
CASE
WHEN qte_vendue > 15 THEN
RETURN ('forte');
WHEN
qte_vendue BETWEEN 11 AND 15 THEN RETURN ('moyenne');
ELSE
RETURN('faible');
END CASE;
END fDemande;
/
SHOW ERRORS

> Solution n19 (exercice p. 52)


1

SELECT num, fDemande(num) FROM produit;

> Solution n20 (exercice p. 52)


1
2
3

INSERT INTO inventaire


SELECT num, designation, prix, fDemande(num)
FROM produit;

> Solution n21 (exercice p. 52)


1
2
3
4
5
6
7
8
9
10
11
12
13

CREATE PROCEDURE nb_fact(num_client IN NUMBER, nb OUT NUMBER, ca OUT


NUMBER)
IS
BEGIN
SELECT COUNT(f.num) INTO nb
FROM facture f
WHERE f.client=num_client;
SELECT sum(p.prix*lf.qte) INTO ca
FROM produit p, facture f, ligne_fact lf
WHERE p.num=lf.produit
AND lf.facture=f.num
AND f.client=num_client;
END nb_fact;
/

> Solution n22 (exercice p. 52)


78

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Solution des exercices

1
2
3
4
5
6
7
8
9
10
11
12

SET SERVEROUTPUT ON
DECLARE
client NUMBER;
nb NUMBER;
ca NUMBER;
BEGIN
client:=1;
nb_fact(client, nb, ca);
DBMS_OUTPUT.PUT_LINE (nb);
DBMS_OUTPUT.PUT_LINE (ca);
END;
/

> Solution n23 (exercice p. 53)


1
2
3
4
5
6
7
8
9
10
11
12
13
14

SET SERVEROUTPUT ON
DECLARE
nb NUMBER;
ca NUMBER;
CURSOR c_client IS SELECT num FROM client;
BEGIN
FOR client IN c_client LOOP
nb_fact(client.num, nb, ca);
DBMS_OUTPUT.PUT_LINE('Client' || client.num);
DBMS_OUTPUT.PUT_LINE (nb || '/' || ca);
DBMS_OUTPUT.PUT_LINE('-----------------');
END LOOP;
END;
/

> Solution n24 (exercice p. 53)


1
2
3
4
5
6
7
8
9

CREATE TRIGGER TR_STOCK_AUDIT


AFTER INSERT ON ligne_fact
FOR EACH ROW
BEGIN
UPDATE PRODUIT p
SET p.stock=p.stock - :new.qte
WHERE p.num= :new.produit;
END;
/

> Solution n25 (exercice p. 54)


1
2
3
4
5
6
7
8
9

CREATE TABLE audit_stock (


id INTEGER,
message VARCHAR(128),
datealert DATE,
produit NUMBER,
stock NUMBER,
CONSTRAINT PK_AUDIT_STOCK PRIMARY KEY (id),
CONSTRAINT FK_AUDIT_STOCK_PRODUIT FOREIGN KEY (produit) REFERENCES
PRODUIT(num)
);

> Solution n26 (exercice p. 54)


1
2
3

CREATE OR REPLACE TRIGGER TR_STOCK_AUDIT


AFTER INSERT ON ligne_fact
FOR EACH ROW

Solution des exercices


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

DECLARE
new_stock NUMBER;
BEGIN
UPDATE PRODUIT p
SET p.stock = p.stock - :new.qte
WHERE p.num = :new.produit;
SELECT stock INTO new_stock
FROM produit
WHERE num = :new.produit;
IF new_stock <= 5 THEN
INSERT INTO AUDIT_STOCK VALUES (
'Attention : rupture de stock imminente',
sysdate,
:new.produit,
new_stock
);
END IF;
END;
/

> Solution n27 (exercice p. 55)


1
2
3
4
5
6

CREATE TABLE employee (


id NUMBER(7),
last_name VARCHAR2(25),
first_name VARCHAR2(25),
dept_id NUMBER(7)
);

> Solution n28 (exercice p. 55)


1
1
2
3
4
5
6

DESCRIBE EMPLOYEE
Name
Null?
Type
-------------------ID NUMBER(7)
LAST_NAME
VARCHAR2(25)
FIRST_NAME
VARCHAR2(25)
DEPT_ID NUMBER(7)

> Solution n29 (exercice p. 55)


1

ALTER TABLE employee MODIFY(last_name VARCHAR2(50));

DESCRIBE EMPLOYEE

1
2
3

...
LAST_NAME
...

VARCHAR2(50)

> Solution n30 (exercice p. 55)


1

80

SELECT table_name

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Solution des exercices


2
3
1
2
3

FROM user_tables
WHERE table_name ='EMPLOYEE';
TABLE_NAME
-------------EMPLOYEE

> Solution n31 (exercice p. 56)


1

ALTER TABLE employee ADD CONSTRAINT employee_id_pk PRIMARY KEY (id);

> Solution n32 (exercice p. 56)


1
2
3

SELECT constraint_name, constraint_type


FROM user_constraints
WHERE table_name ='EMPLOYEE';

1
2
3

CONSTRAINT_NAME
---------EMPLOYEE_ID_PK

CONSTRAINT_TYPE
PRIMARY KEY

Image 13 Contraintes sur la table EMPLOYEE

> Solution n33 (exercice p. 56)


1
2
3
1
2
3
4

SELECT object_name, object_type


FROM user_objects
WHERE object_name LIKE 'EMPLOYEE%';
OBJECT_NAME
---------------EMPLOYEE
EMPLOYEE_ID_PK

OBJECT_TYPE
TABLE
INDEX

> Solution n34 (exercice p. 56)


1

ALTER TABLE employee ADD (salary

> Solution n35 (exercice p. 56)


1

RENAME employee TO employee2;

NUMBER(7));

Solution des exercices

> Solution n36 (exercice p. 56)


1

DROP TABLE employee2;

> Solution n37 (exercice p. 56)


1
2

SELECT ename||', '||job "EMPLOYE ET FONCTION"


FROM emp;

1
2
3
4
5

EMPLOYE ET FONCTION
------------------KING, PRESIDENT
BLAKE, MANAGER
CLARK, MANAGER

> Solution n38 (exercice p. 56)


1
2
3
4
5
6
1
2
3
4
5
6

SELECT ename, hiredate


FROM emp
WHERE hiredate BETWEEN
TO_DATE('20-Feb-1981','DD-MON-YYYY')
AND TO_DATE('01-May-1981','DD-MON-YYYY')
ORDER BY hiredate;
ENAME
HIREDATE
----------ALLEN
20-FEB-81
WARD
22-FEB-81
JONES 02-APR-81
BLAKE 01-MAY-81

> Solution n39 (exercice p. 56)


1
2
3

SELECT ename
FROM emp
WHERE ename LIKE '%L%L%';

> Solution n40 (exercice p. 57)


1
2
3
4

SELECT ename, job, sal


FROM emp
WHERE job IN ('CLERK', 'ANALYST')
AND sal NOT IN (1000, 3000, 5000);

> Solution n41 (exercice p. 57)


1
2

82

SELECT ename, ROUND(MONTHS_BETWEEN (SYSDATE, hiredate)) MONTHS_WORKED


FROM emp;

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Solution des exercices

> Solution n42 (exercice p. 57)


1
2
3
4
5
6
7

SELECT
ename||' gagne '
|| TO_CHAR(sal, 'fm$99,999.00')
|| ' par mois mail il veut '
|| TO_CHAR(sal * 3, 'fm$99,999.00')
|| '.' "SALAIRES DE REVES"
FROM emp;

> Solution n43 (exercice p. 57)


1
2
3
4
5

SELECT ROUND(MAX(sal),0) "Maximum",


ROUND(MIN(sal),0) "Minimum",
ROUND(SUM(sal),0) "Sum",
ROUND(AVG(sal),0) "Average"
FROM emp;

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

83

Solution des
exercices
> Solution n1 (exercice p. 28,59)
erreur
Cette fonction renvoie le nom pass en paramtre si celui-ci est prsent une et une
seule fois dans la table "t_personnes". Si le nom est prsent plus d'une fois, une
exception est dclenche, car la clause SELECT INTO ne doit renvoyer qu'un seul
enregistrement.

> Solution n2 (exercice p. 30,59)


SELECT a FROM t;
SELECT count(a) FROM t;
SELECT avg(a) FROM t;
La fonction fait la somme des valeurs de t.a, donc aucune rponse ne correspond.

> Solution n3 (exercice p. 36,60)


2
Le trigger signifie que b prend l'ancienne valeur de a chaque mise jour de a ou
b.
Soit le contenu de la table t :
1. Aprs Create :
2. Aprs Insert : (1,1) (trigger ne se dclenche pas)
3. Aprs Update n1 : (2,1) (trigger se dclenche et modifie b)
4. Aprs Update n2 : (3,2) (trigger se dclenche et modifie b)
Donc le SELECT renvoie la valeur 2 (la valeur de b, en notant qu'il y a un seul
tuple).
La diffrence entre un trigger BEFORE et AFTER est que dans un trigger BEFORE
UPDATE vous avez le droit de modifier les valeurs de mise jour ( travers les
:new), tandis que sur un AFTER UPDATE vous ne pouvez plus (la mise jour est
termine).
On pourrait plus justement traduire le BEFORE UPDATE par "PENDANT LA MISE A
JOUR" et le AFTER UPDATE par "UNE FOIS LA MISE A JOUR TERMINEE".
Donc BEFORE UPDATE ne veut pas dire que le UPDATE se fera aprs le TRIGGER,
mais que le TRIGGER peut redfinir les valeurs :new de mise jour.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

85

Solution des exercices

On notera que c'est la mme chose pour un BEFORE INSERT.

> Solution n4 (exercice p. 60)


1

> Solution n5 (exercice p. 61)


Exercice
Valide
Invalide

Exercice
Invalide
Valide
Un seul identifiant est autoris chaque ligne de dclaration.

Exercice
Invalide
Valide
Une variable NOT NULL doit tre initialise.

Exercice
Invalide
Valide
1 n'est pas une expression boolenne.

> Solution n6 (exercice p. 62)


Exercice

86

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine Vincent)

Solution des exercices

priodiquement
l'initialisation de la base de donnes
suite l'occurrence d'un vnement prcis
en invoquant la commande run
suite l'appel explicite du trigger

Exercice
priodiquement
l'initialisation de la base de donnes
suite l'occurrence d'un vnement prcis
en invoquant la commande run
suite l'appel explicite de la procdure

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

87

Signification des
abrviations
-

BD
CSV
OS
SGBD
XML

Base de Donnes
Comma Separated Values
Operating Systme (Systme d'Exploitation)
Systme de Gestion de Bases de Donnes
eXtensible Markup Language

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

89

Bibliographie

[Abbey01] ABBEY MICHAEL, COREZ MICHAEL, ABRAMSON IAN, Oracle 9i : Notions fondamentales,
CampusPress, 2001.
[Delmal01] DELMAL PIERRE. SQL2 SQL3, applications Oracle. De Boeck Universit, 2001.
[Mata03] MATA-TOLEDO RAMON A., CUSHMAN PAULINE K.. Programmation SQL. Ediscience, 2003.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

91

Webographie

[w_loria.fr/~roegel(1)] ROEGEL DENIS, Oracle : SQL, http://www.loria.fr/~roegel/cours/iut/oracle-sql.pdf ,


1999.
[w_stanford.edu]
STANFORD
UNIVERSITY,
Notes on
db.stanford.edu/~ullman/fcdb/oracle.html , consult en 2004.

the

Oracle

DBMS,

http://www-

[w_ualberta.ca] UNIVERSITY OF ALBERTA, Computing Science 291/391 : Laboratory Manual,


http://ugweb.cs.ualberta.ca/~c391/manual/title.html , 1995.

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

93

Index
:new p.34
:old p.34
%TYPE........................... p.24
Application...................... p.20
Chane........................... p.17
Cl p.15
CSV p.
Curseur.................. p.24, 28, 43
CURSOR......................... p.28
date p.17, 19
DBMS_OUTPUT................ p.25
Dclencheur............ p.32, 34, 35
Dictionnaire.................... p.14
Domaine......................... p.13
Erreur............................ p.30

Etat p.20
EXCEPTION..................... p.30
Fonction.................. p.17, 19, 25
Fonction stocke.............. p.43
FOR p.25
IF
p.25
INTO p.27
Langage..................... p.23, 23
LMD p.16, 21
Oracle........................ p.12, 43
PL/SQL........................... p.43
Procdure....................... p.25
Procdure stocke........... p.43
RECORD......................... p.24
REPEAT.......................... p.25

Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine


Vincent)

SELECT.......................... p.27
Squence....................... p.43
Sous-requte.................. p.43
SQL Developer................ p.36
String............................. p.17
SUBSTR.......................... p.17
TO_CHAR.................... p.17, 19
TO_DATE.................... p.17, 19
Trigger........................... p.43
TRIGGER................. p.32, 34, 35
Type p.24
Variable.......................... p.24
Vue p.43
WHILE............................ p.25

95