Conception de bases de donnes
Technologie
Oracle :
Extensions
procdurales
SQL
[Link]
STPHANE CROZAT
Paternit - Partage des Conditions Initiales l'Identique :
[Link]
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', [Link], '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', [Link], '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', [Link], '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 [Link]%TYPE;
vPrenom [Link]%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([Link])) || ' ' ||
INITCAP(TRIM([Link])));
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
:[Link] := :[Link]+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', [Link], '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 (:[Link], :[Link]);
ELSIF INSERTING THEN
DELETE FROM tIntervenantSav WHERE pknom = :[Link];
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 : [Link]
Il est possible de tlcharger gratuitement Oracle des fins de
dveloppement
et
de
prototypage
:
[Link]
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.
[Link]
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', [Link], 'Introduction','C', '01-JAN2001', 'CROZAT');
INSERT INTO tCours (pkannee, pknum, titre, type, debut,
fkintervenant)
VALUES ('2003', [Link], '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 - [Link]
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', [Link], '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
[Link]
[Link]
[Link]
[Link]
[Link]
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.
[Link]
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
[Link]
7 - [Link]
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 [Link];
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
[Link]
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 [Link]%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)
[Link]
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 [Link]%TYPE;
v_loc [Link]%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 [Link]%TYPE;
vPrenom [Link]%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([Link])) || ' ' ||
INITCAP(TRIM([Link])));
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
:[Link] := :[Link]+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', [Link], '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 (:[Link], :[Link]);
ELSIF INSERTING THEN
DELETE FROM tIntervenantSav WHERE pknom = :[Link];
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
[Link]
(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 : [Link]
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 @[Link]
Exemple
1
2
3
42
: [Link]
@[Link]
@[Link]
@[Link]
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([Link]), 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([Link]*[Link])), 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' || [Link]);
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=:[Link];
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 [Link]
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 [Link]
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, [Link] 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 [Link], [Link], sum([Link]) as nb
from produit p, ligne_fact lf
where [Link]=[Link]
group by [Link], [Link]
order by nb desc;
> Solution n9 (exercice p. 48)
1
2
3
4
select [Link], [Link], [Link], sum([Link]*[Link])
from client c, produit p, facture f, ligne_fact lf
where [Link]=[Link]
and [Link]=[Link]
Stphane Crozat (Contributions : Dritan Nace, Yacine Challal, Antoine
Vincent)
75
Solution des exercices
5
6
7
and [Link]=[Link]
group by [Link], [Link], [Link]
order by sum([Link]*[Link]) DESC;
> Solution n10 (exercice p. 49)
1
2
3
4
5
6
7
8
9
select client, avg(montant) moy
from (
select [Link] as client, [Link], sum([Link]*[Link]) as montant
from facture f, ligne_fact lf, client c, produit p
where [Link]=[Link] and [Link]=[Link] and [Link]=[Link]
group by [Link], [Link]
)
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 [Link], sum([Link])
from produit p, ligne_fact lf
where [Link]=[Link]
group by [Link];
> 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 [Link], [Link], [Link], sum([Link]*[Link]) chiffre_affaire,
CASE
WHEN sum([Link]*[Link])>500 THEN 'VIP'
WHEN sum([Link]*[Link]) BETWEEN 50 AND 500 THEN 'Ordinaire'
ELSE 'Potentiel'
END categorie
FROM client c, produit p, facture f, ligne_fact lf
WHERE [Link]=[Link]
AND [Link]=[Link]
AND [Link]=[Link]
GROUP BY [Link], [Link], [Link];
> Solution n15 (exercice p. 50)
1
2
3
4
5
6
7
8
9
10
11
12
CREATE VIEW v_chiffre_affaire AS
SELECT [Link], [Link], [Link], sum([Link]*[Link]) chiffre_affaire,
CASE
WHEN sum([Link]*[Link])>500 THEN 'VIP'
WHEN sum([Link]*[Link]) BETWEEN 50 AND 500 THEN 'Ordinaire'
ELSE 'Potentiel'
END categorie
FROM client c, produit p, facture f, ligne_fact lf
WHERE [Link]=[Link]
AND [Link]=[Link]
AND [Link]=[Link]
GROUP BY [Link], [Link], [Link];
> 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([Link]) INTO qte_vendue
FROM ligne_fact lf
WHERE [Link]=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([Link]) INTO qte_vendue
FROM ligne_fact lf
WHERE [Link]=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([Link]) INTO nb
FROM facture f
WHERE [Link]=num_client;
SELECT sum([Link]*[Link]) INTO ca
FROM produit p, facture f, ligne_fact lf
WHERE [Link]=[Link]
AND [Link]=[Link]
AND [Link]=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([Link], nb, ca);
DBMS_OUTPUT.PUT_LINE('Client' || [Link]);
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 [Link]=[Link] - :[Link]
WHERE [Link]= :[Link];
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 [Link] = [Link] - :[Link]
WHERE [Link] = :[Link];
SELECT stock INTO new_stock
FROM produit
WHERE num = :[Link];
IF new_stock <= 5 THEN
INSERT INTO AUDIT_STOCK VALUES (
'Attention : rupture de stock imminente',
sysdate,
:[Link],
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, [Link] ,
1999.
[w_stanford.edu]
STANFORD
UNIVERSITY,
Notes on
[Link]/~ullman/fcdb/[Link] , consult en 2004.
the
Oracle
DBMS,
[Link]
[w_ualberta.ca] UNIVERSITY OF ALBERTA, Computing Science 291/391 : Laboratory Manual,
[Link] , 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