Vous êtes sur la page 1sur 44

Introduction aux langage SQL

Alexandre Mesl

4 avril 2016
Table des matires

1 Notes de cours 2
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 Quest-ce quun SGBDR ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.2 SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.3 Connexion une base de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.4 Consultation des tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.5 Organisation relationnelle des donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Contraintes dclaratives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.1 Valeurs par dfaut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.2 Champs non renseigns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.3 Cl primaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.4 Cl trangre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.5 Syntaxe alternative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3 Introduction aux requtes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3.1 Complments sur SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3.2 Instruction WHERE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3.3 Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3.4 Suppression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3.5 Mise jour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4 Jointures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.4.1 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.4.2 Produit cartsien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.4.3 Jointure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.4.4 Jointures rflexives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.5 Agrgation de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5.1 Fonctions dagrgation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5.2 Groupage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.6 Vues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.6.1 Dfinition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.6.2 Syntaxe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.6.3 Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.6.4 Suppression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.7 Requtes imbriques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.7.1 Sous requtes renvoyant une valeur scalaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.7.2 Sous requtes renvoyant une colonne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.7.3 Sous requtes non correles renvoyant une table . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.7.4 Sous requtes correles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.8 Procdures stockes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.8.1 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.8.2 SQL Procdural . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.8.3 Procdures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.8.4 Curseurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.8.5 Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

1
.1 Scripts de cration de tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
.2 Livraisons Sans contraintes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
.3 Modules et prerequis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
.4 Gomtrie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
.5 Livraisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
.6 Arbre gnalogique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
.7 Comptes bancaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
.8 Comptes bancaires avec exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
.9 Secrtariat pdagogique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
.10 Mariages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
.11 Bibliothque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

2
Chapitre 1

Notes de cours

1.1 Introduction
1.1.1 Quest-ce quun SGBDR ?
Un SGBD (Systme de Gestion de Bases de Donnes) est un logiciel qui stocke des donnes de faon organises
et cohrentes. Un SGBDR (Systme de Gestion de Bases de Donnes Relationnelles) est le type particulier de SGBD
qui fera lobjet de ce cours. Il vous sera dcrit plus tard ce qui fait quune bases de donnes est relationnelle.
Les bases de donnes les plus rpandues sont :
Oracle, qui est considr comme un des SGBDR les plus performants.
Microsoft SQL Server, la mouture de microsoft, qui est intgr au framework .NET.
mySQL, un logiciel libre fonctionnant souvent de pair avec Apache et Php, et de ce fait trs rpandu dans la
programmation web.
Access, incorpor Microsoft Office. Il prsente lnorme avantage de mettre disposition de lutilisateur une
interface graphique. En contrepartie il est mono-utilisateur et de faible capacit.
Les SGBDRs sont gnralement des serveurs auxquels des clients se connectent, il doivent supporter plusieurs
connections simultanes. Les clients dialoguent alors avec le serveur pour lire ou crire des donns dans la base.

1.1.2 SQL
Le SQL, Structured Query Language, est un langage Standard permettant un client de communiquer des ins-
tructions la base de donnes. Il se dcline en quatre parties :
le DDL (Data definition language) comporte les instructions qui permettent de dfinir la faon dont les donnes
sont reprsentes.
le DML (Data manipulation language) permet dcrire dans la base et donc de modifier les donnes.
le DQL (Data query language) est la partie la plus complexe du SQL, elle permet de lire les donnes dans la
base laide de requtes.
le DCL (Data control language), qui ne sera pas vu dans ce cours permet de grer les droits daccs aux donnes.
A cela sajoute des extensions procdurales du SQL (appel PL/SQL en Oracle). Celui-ci permet dcrire des scripts
excuts par le serveur de base de donnes.

1.1.3 Connexion une base de donnes


Dans une base de donnes relationnelle, les donnes sont stockes dans des tables. Une table est un tableau deux
entres. Nous allons nous connecter une base de donnes pour observer les tables.

Oracle
Sous oracle, le client sappelle SQL+, le compte utilisateur par dfaut a pour login scott et password tiger.
La liste des tables saffiche en utilisant linstruction
sql> SELECT TABLE_NAME FROM USER_TABLES

3
mySQL
La mthode la plus simple pour sinitier mysql est dutiliser un kit de easyphp, wamp, etc. Vous disposez dans
ce cas dune option vous permettant douvrir une console mysql.
La liste des bases de donnes stockes dans le serveur sobtient avec linstruction
sql> show databases

++
| Database |
++
| information_schema |
| arbreGenealogique |
| banque |
| clients |
| geometrie |
| livraisons |
| playlist |
| repertoire |
| secretariat |
| test |
| utilisateurs |
++

On se connecte lune des bases de donnes avec linstruction


sql> use nomdelabase

1.1.4 Consultation des tables


Une fois dans la base, on obtient la liste des tables avec linstruction
sql> show tables

++
| Tables_in_livraisons |
++
| DETAILLIVRAISON |
| FOURNISSEUR |
| LIVRAISON |
| NB_FOURNISSEURS_PAR_PRODUIT |
| NB_PROD_PAR_FOU |
| PRODUIT |
| PROPOSER |
++

On affiche la liste des colonnes dune table avec linstruction


sql> desc PRODUIT

+++++++
| Field | Type | Null | Key | Default | Extra |
+++++++
| numprod | i n t ( 1 1 ) | NO | PRI | 0 | |
| nomprod | varchar ( 3 0 ) | YES | | NULL | |
+++++++

Le contenu dune table saffiche avec linstruction


sql> SELECT
sql> FROM PRODUIT

4
+++
| numprod | nomprod |
+++
| 1 | Roue de secours |
| 2 | Poupee Batman |
| 3 | Cotons tiges |
| 4 | Cornichons |
+++

1.1.5 Organisation relationnelle des donnes


Nous utiliserons pour commencer les types suivants :
numrique entier : int
numrique point fixe : number (Oracle seulement)
numrique point flottant : real
chane de caractres : varchar(taille) ou varchar2(taille) (Oracle seulement).

Crer des tables


Voici un exemple de cration de table :
sql> CREATE TABLE CLIENT (
sql> numcli int ,
sql> nomcli varchar ( 3 2 ) ) ;
sql> desc CLIENT ;

+++++++
| Field | Type | Null | Key | Default | Extra |
+++++++
| numcli | i n t ( 1 1 ) | YES | | NULL | |
| nomcli | varchar ( 3 2 ) | YES | | NULL | |
+++++++

Ajouter une ligne dans une table


Voici un exemple dinsertion de donnes dans une table :
sql> INSERT INTO CLIENT ( numcli , nomcli )
sql> VALUES ( 1 , Marcel ) , ( 2 , Gg ) ;
sql> SELECT FROM CLIENT ;

+++
| numcli | nomcli |
+++
| 1 | Marcel |
| 2 | Gg |
+++

Attention, chaque commande SQL se termine par un point-virgule !

Suppression dune table


Une table se supprime avec linstruction DROP TABLE.
sql> DROP TABLE CLIENT ;

5
1.2 Contraintes dclaratives
1.2.1 Valeurs par dfaut

sql> create table client


sql> (
sql> numcli int ,
sql> nom varchar ( 2 5 6 ) default Moi ,
sql> prenom varchar ( 2 5 6 )
sql> )

fait de Moi le nom par dfaut.

1.2.2 Champs non renseigns

sql> create table client


sql> (
sql> numcli int ,
sql> nom varchar ( 2 5 6 ) NOT NULL,
sql> prenom varchar ( 2 5 6 ) NOT NULL
sql> )

force la saisie des champs nom et prnom.

1.2.3 Cl primaire
Une cl primaire est :
toujours renseigne
unique
On peut prciser PRIMARY KEY dans la cration de table
sql> create table client
sql> (
sql> numcli i n t PRIMARY KEY,
sql> nom varchar ( 2 5 6 ) ,
sql> prenom varchar ( 2 5 6 )
sql> )

La colonne numcli est cl primaire, toute insertion ne respectant pas la contrainte de cl primaire sera refuse par
le SGBD.

1.2.4 Cl trangre
Dans le cas o lon souhaite garder en mmoire des factures mises par des clients, la faon de faire est de crer
une deuxime table contenant la liste des factures :
sql> create table facture
sql> (
sql> numfact i n t PRIMARY KEY,
sql> montantFacture i n t
sql> numcli i n t REFERENCES CLIENT ( numCli )
sql> );

Le champ numCli dans cette table est cl trangre, ce qui signifie quune ligne ne pourra tre insre dans la table
facture que si le numcli de cette ligne existe dans la colonne numcli de la table client.
La syntaxe est
REFERENCES <nomtable> (<nomcolonne >)

6
1.2.5 Syntaxe alternative
Il est possible de dfinir les contraintes aprs la cration dune table.
sql> ALTER TABLE nomtable
sql> ADD [CONSTRAINT nomcontrainte ] descriptioncontrainte ;

descriptioncontrainte dune cl primaire :


PRIMARY KEY( colonne1 , . . . , colonnen )

descriptioncontrainte dune cl trangre :


FOREIGN KEY( colonne1 , . . . , colonnen )
REFERENCES tablereferencee ( colonne1 , . . . , colonnen )

Il est aussi possible de placer une descriptioncontrainte dans le CREATE TABLE. Par exemple,
sql> create table facture
sql> (
sql> numfact int ,
sql> montantFacture i n t
sql> numcli int ,
sql> PRIMARY KEY ( numfact ) ,
sql> FOREIGN KEY nucli REFERENCES CLIENT ( numcli )
sql> );

On remarque quil est possible de nommer une contrainte. Cest utile si on souhaite la supprimer :
sql> ALTER TABLE nomtable DROP CONSTRAINT nomcontrainte ;

Pour lister les contraintes sous Oracle, on utilise la commande :


sql> SELECT FROM USER_CONSTRAINTS ;

Sous mySQL :
sql> SHOW TABLE STATUS ;

7
1.3 Introduction aux requtes
1.3.1 Complments sur SELECT
Il est possible dutiliser SELECT pour nafficher que certaines colonnes dune table. Syntaxe :
SELECT <colonne_1 >, <colonne_2 >, . . . , <colonne_n>
FROM <table>

Cette instruction sappelle une requte, elle affichera pour chaque ligne de la table les valeurs des colonnes colonne1
colonnen . Il est possible de supprimer les lignes en double laide du mot-cl DISTINCT. Par exemple :
SELECT DISTINCT <colonne_1 >, <colonne_2 >, . . . , <colonne_n>
FROM <table>

Pour trier les donnes, on utilise ORDER BY. Exemple :


SELECT <colonne_1 >, <colonne_2 >, . . . , <colonne_n>
FROM <table>
ORDER BY <colonne_1bis >, <colonne_2bis >, . . . , <colonne_nbis>

Cette instruction trie les donnes par colonne1bis croissants. En cas dgalit, le tri est fait par colonne2bis croissants,
etc. Pour trier par ordre dcroissant, on ajoute DESC aprs le nom de la colonne choisie comme critre dcroissant. Par
exemple :
SELECT <colonne_1 >, <colonne_2 >, . . . , <colonne_n>
FROM <table>
ORDER BY <colonne_1bis> DESC, <colonne_2bis >, . . . , <colonne_nbis>

1.3.2 Instruction WHERE


Cette instruction permet de ne slectionner que certaines lignes de la table. Par exemple la requte va afficher le
nom du produit numro 1 :
sql> SELECT nomprod
sql> FROM produit
sql> WHERE numprod = 1

La syntaxe gnrale est


SELECT <colonne_1 >, <colonne_2 >, . . . , <colonne_n>
FROM <table>
WHERE <condition>

condition sera value pour chaque ligne de la table, et seules celles qui vfieront cette condition feront partie du
rsultat de la requte.

1.3.3 Conditions
Comparaison
Les conditions peuvent tre des relations dgalit (=), de diffrence (<>), dingalit (<, >, >= ou <=) sur des
colonnes :
numero_client = 2
nom_client = Marcel
prenom_client <> Ginette
salary < 230
taxes >= 23000

8
Ngation
La ngation dune condition sobtient laide de NOT. Par exemple, il est possible de r-ecrire les conditions ci-avant :
NOT ( numero_client <> 2 )
NOT ( nom_client <> Marcel )
NOT ( prenom_client = Ginette )
NOT ( salary >= 2 3 0 )
NOT ( taxes < 2 3 0 0 0 )

Connecteurs logiques
De mme, vous avez votre disposition tous les connecteurs logiques binaires : AND, OR. Ainsi, les deux conditions
suivantes sont les mmes :
NOT( ( nom = Raymond ) AND ( prenom <> Huguette ) )
( nom <> Raymond ) OR ( prenom = Huguette )

NULLit
Un champ non renseign a la valeur NULL, dans une comparaison, NULL nest jamais gal quelque valeur quil
soit ! La condition suivante est toujours fausse :
NULL = NULL;

La requte suivante ne renvoie aucune ligne :


sql> INSERT INTO MP3 ( numMp3 ) VALUES ( 3 ) ;
sql> SELECT
sql> FROM MP3
sql> WHERE nomMp3 = NULL;

Pour tester la nullit dun champ, on utilise IS NULL, par exemple :


sql> SELECT
sql> FROM MP3
sql> WHERE nomMp3 IS NULL;

+++
| numMp3 | nomMp3 |
+++
| 3 | NULL |
+++

La non-nullit se teste de deux faons :


WHERE NOT ( nomMp3 IS NULL) ;

ou encore
sql> SELECT
sql> FROM MP3
sql> WHERE nomMp3 IS NOT NULL;

+++
| numMp3 | nomMp3 |
+++
| 1 | Get Lucky |
| 2 | Locked Down |
+++

9
Encadrement
Une valeur numrique peut tre encadre laide de loprateur BETWEEN, par exemple les deux conditions suivantes
sont quivalentes :
SALAIRE BETWEEN 1000 AND 5000
( SALAIRE >= 1 0 0 0 ) AND ( SALAIRE <= 5 0 0 0 )

Inclusion
Loprateur IN permet de tester lappartenance une liste de valeurs. Les deux propositions suivantes sont qui-
valentes
NAME IN ( Gg , Ginette , Marcel )
( NAME = Gg ) OR ( NAME = Ginette ) OR ( NAME = Marcel )

LIKE
LIKE sert comparer le contenu dune variable un littral gnrique. Par exemple, la condition
NAME LIKE M%

sera vrifie si NAME commence par un M. Ca fonctionne aussi sur les valeurs de type numrique, la condition
SALARY LIKE %000000000

sera vrifie si SALARY se termine par 000000000. Le caractre % peut remplacer dans le littral nimporte que suite,
vide ou non, de caractres ; il a le mme rle que * en DOS et en SHELL. Le caractre _ remplace un et un seul
caractre dans le littral. Par exemple, la condition
NAME LIKE K_r %

ne sera vrifie que si NAME commence par un K et contient un r en troisime position.

1.3.4 Suppression
Lexpression
DELETE FROM <NOMTABLE>
WHERE <CONDITION>

efface de la table NOMTABLE toutes les lignes vrifiant condition. Attention ! La commande
DELETE FROM <NOMTABLE>

efface toutes les lignes de la table NOMTABLE !

1.3.5 Mise jour


Lexpression
UPDATE <NOMTABLE>
SET <colonne_1> = <valeur_1 >,
<colonne_2> = <valeur_2 >,
... ,
<colonne_n> = <valeur_n>
WHERE <CONDITION>

modifie les lignes de la table NOMTABLE vrifiant condition. Elle affecte au champ colonnei la valeur valeuri . Par
exemple,

10
sql> UPDATE CLIENT
sql> SET prenomcli = Dark
sql> WHERE nomcli = Vador

affecte la valeur Dark aux champs prenomcli de toutes les lignes dont la valeur nomcli est gale Vador. Il
est possible, dans une modification, dutiliser les valeurs des autres champs de la ligne, voire mme lancienne valeur
de ce champ. Par exemple,
sql> UPDATE OPERATION
sql> SET montantoper = montantoper + 5000

augmente les montants de toutes les oprations bancaires de 5000 (choisissez lunit !).

11
1.4 Jointures
1.4.1 Principe
Nous utiliserons pour ce cours les donnes de .3.
Si on souhaite connatre les numros des modules pr-requis pour sinscrire dans le module PL/SQL Oracle, il
nous faut tout dabord le numro de ce module :
sql> SELECT numMod
sql> FROM MODULE
sql> WHERE nomMod = PL / SQL Oracle

++
| numMod |
++
| 6 |
++

Ensuite, cherchons les numros des modules pr-requis pour sinscrire dans le module numro 6,
sql> SELECT numModPrereq
sql> FROM PREREQUIS
sql> WHERE numMod = 6 ;

++
| numModPrereq |
++
| 1 |
| 5 |
++

Et pour finir, allons rcuprer les noms de ces modules,


sql> SELECT nomMod
sql> FROM MODULE
sql> WHERE numMod IN ( 1 , 5 ) ;

++
| nomMod |
++
| Oracle |
| Merise |
++

Vous tes probablement tous en train de vous demander sil nexiste pas une mthode plus simple et plus rapide,
et surtout une faon dautomatiser ce que nous venons de faire. Il existe un moyen de slectionner des donnes dans
plusieurs tables simultanment. Pour traiter la question ci-dessus il suffisait de saisir :
sql> SELECT m2 . nomMod
sql> FROM MODULE m1 , MODULE m2 , PREREQUIS p
sql> WHERE m1 . numMod = p . numMod
sql> AND m2 . numMod = p . numModprereq
sql> AND m1 . nomMod = PL / SQL Oracle ;

++
| nomMod |
++
| Oracle |
| Merise |
++

Le but de ce chapitre est dexpliciter ce type de commande.

12
1.4.2 Produit cartsien
Linstruction SELECT ... FROM ... peut stendre de la faon suivante :
sql> SELECT <listecolonnes>
sql> FROM <listetables>

Lexemple ci-dessous vous montre le rsultat dune telle commande.


sql> SELECT
sql> FROM PROPOSER , PRODUIT ;

++++++
| numfou | numprod | prix | numprod | nomprod |
++++++
| 1 | 1 | 200 | 1 | Roue de secours |
| 1 | 2 | 15 | 1 | Roue de secours |
| 2 | 2 | 1 | 1 | Roue de secours |
| 3 | 3 | 2 | 1 | Roue de secours |
| 1 | 1 | 200 | 2 | Poupee Batman |
| 1 | 2 | 15 | 2 | Poupee Batman |
| 2 | 2 | 1 | 2 | Poupee Batman |
| 3 | 3 | 2 | 2 | Poupee Batman |
| 1 | 1 | 200 | 3 | Cotons tiges |
| 1 | 2 | 15 | 3 | Cotons tiges |
| 2 | 2 | 1 | 3 | Cotons tiges |
| 3 | 3 | 2 | 3 | Cotons tiges |
| 1 | 1 | 200 | 4 | Cornichons |
| 1 | 2 | 15 | 4 | Cornichons |
| 2 | 2 | 1 | 4 | Cornichons |
| 3 | 3 | 2 | 4 | Cornichons |
++++++

Placer une liste de tables dans le FROM revient former toutes les combinaisons de lignes possibles. Cependant, cela
a relativement peu de sens.

1.4.3 Jointure
Il serait plus intressant, dans le cas prsent, de ne voir safficher que des lignes dont les numros de produits
concordent. Pour ce faire, il suffit dutiliser WHERE. Par exemple,
sql> SELECT
sql> FROM PROPOSER , PRODUIT
sql> WHERE PROPOSER . numprod = PRODUIT . numprod ;

++++++
| numfou | numprod | prix | numprod | nomprod |
++++++
| 1 | 1 | 200 | 1 | Roue de secours |
| 1 | 2 | 15 | 2 | Poupee Batman |
| 2 | 2 | 1 | 2 | Poupee Batman |
| 3 | 3 | 2 | 3 | Cotons tiges |
++++++

Nous avons mis en correspondance des lignes de la table proposer avec des lignes de la table produit en utilisant le
fait que numprod est une cl trangre dans proposer. Comme la colonne numprod apparat deux fois dans la requte,
il est ncessaire de la prfixer par le nom de la table de sorte que chaque colonne puisse tre dsigne de faon non
ambigu. Si on veut mettre face face les noms des produits et les noms des fournisseurs, il suffit de saisir la requte
sql> SELECT nomfou , nomprod
sql> FROM PRODUIT , FOURNISSEUR , PROPOSER

13
sql> WHERE PRODUIT . numProd = PROPOSER . numProd
sql> AND FOURNISSEUR . numFou = PROPOSER . numFou ;

+++
| nomfou | nomprod |
+++
| f1 | Roue de secours |
| f1 | Poupee Batman |
| f2 | Poupee Batman |
| f3 | Cotons tiges |
+++

1.4.4 Jointures rflexives


En utilisant la syntaxe suivante, il est possible de renommer les tables,
sql> FROM <table_1> <table_1_renommee >, . . . , <table_n> <table_n_renommee>

Reformulons la requte ci-dessus,


sql> SELECT nomfou , nomprod
sql> FROM PRODUIT p , FOURNISSEUR f , PROPOSER pr
sql> WHERE p . numProd = pr . numProd
sql> AND f . numFou = pr . numFou ;

+++
| nomfou | nomprod |
+++
| f1 | Roue de secours |
| f1 | Poupee Batman |
| f2 | Poupee Batman |
| f3 | Cotons tiges |
+++

Le renommage permet entre autres de faire des jointures rflexives, cest dire entre une table et elle mme. Par
exemple, en reprenant la table intervalle,
sql> SELECT FROM INTERVALLE ;

+++
| borneInf | borneSup |
+++
| 0 | 30 |
| 2 | 3 |
| 2 | 56 |
| 5 | 10 |
| 7 | 32 |
| 8 | 27 |
| 12 | 3 |
| 12 | 30 |
| 21 | 8 |
| 34 | 26 |
+++

La commande ci-dessous affiche tous les couples dintervalles ayant une borne en commun,
sql> SELECT FROM INTERVALLE i , INTERVALLE j
sql> WHERE ( i . borneInf = j . borneInf AND i . borneSup < j . borneSup )
sql> OR ( i . borneInf < j . borneInf AND i . borneSup = j . borneSup ) ;

14
+++++
| borneInf | borneSup | borneInf | borneSup |
+++++
| 2 | 3 | 2 | 56 |
| 2 | 3 | 12 | 3 |
| 0 | 30 | 12 | 30 |
| 12 | 3 | 12 | 30 |
+++++

15
1.5 Agrgation de donnes
1.5.1 Fonctions dagrgation
Exemple introductif
Nous voulons connatre le nombre de lignes de table produit. Deux faons de procder :
1. Solution moche
sql> SELECT FROM PRODUIT ;

+++
| numprod | nomprod |
+++
| 1 | Roue de secours |
| 2 | Poupee Batman |
| 3 | Cotons tiges |
| 4 | Cornichons |
+++

On a la rponse avec le nombre de lignes slectionnes.


2. Solution belle
sql> SELECT count ( ) FROM PRODUIT ;

++
| count ( ) |
++
| 4 |
++

La rponse est le rsultat de la requte.

Dfinition
Une fonction dagrgation retourne une valeur calcule sur toutes les lignes de la requte (nombre, moyenne...).
Nous allons utiliser les suivantes :
COUNT(col) : retourne le nombre de lignes dont le champ col est non NULL.
AVG(col) : retourne la moyenne des valeurs col sur toutes les lignes dont le champ col est non NULL.
MAX(col) : retourne la plus grande des valeurs col sur toutes les lignes dont le champ col est non NULL.
MIN(col) : retourne la plus petite des valeurs col sur toutes les lignes dont le champ col est non NULL.
SUM(col) : retourne la somme des valeurs col sur toutes les lignes dont le champ col est non NULL.

Exemples dutilisation
Lexemple suivant retourne le prix du produit propos au prix maximal.
sql> SELECT MAX( prix )
sql> FROM PROPOSER ;

++
| MAX( prix ) |
++
| 200 |
++

Il est possible de renommer la colonne MAX(prix), en utilisant le mot cl AS :

16
sql> SELECT MAX( prix ) AS PRIX_MAXIMAL
sql> FROM PROPOSER ;

++
| PRIX_MAXIMAL |
++
| 200 |
++

Les requtes suivantes rcuprent le nom du fournisseur proposant larticle Poupe Batman au prix le moins lev :
sql> SELECT MIN( prix ) AS PRIX_MINIMUM
sql> FROM PROPOSER PR , PRODUIT P
sql> WHERE PR . numprod = P . numprod
sql> AND nomprod = Poupee Batman ;

++
| PRIX_MINIMUM |
++
| 1 |
++

sql> SELECT nomfou


sql> FROM FOURNISSEUR F , PROPOSER PR , PRODUIT P
sql> WHERE F . numfou = PR . numfou
sql> AND PR . numprod = P . numprod
sql> AND nomprod = Poupee Batman
sql> AND prix = 1 ;

++
| nomfou |
++
| f2 |
++

Il est possible de faire cela avec une seule requte en rcuprant le prix minimum dans une requte imbrique. Mais
cela sera pour un cours ultrieur.

Complments sur COUNT


On rcupre le nombre de ligne retournes par une requte en utilisant COUNT(*). Par exemple, si on souhaite
connatre le nombre de produits proposs par le fournisseur f1 :
sql> SELECT COUNT( ) AS NB_PROD
sql> FROM FOURNISSEUR F , PROPOSER P
sql> WHERE F . numfou = P . numfou
sql> AND nomfou = f1 ;

++
| NB_PROD |
++
| 2 |
++

On aurait aussi pu saisir :


sql> SELECT COUNT( numprod ) AS NB_PROD
sql> FROM FOURNISSEUR F , PROPOSER P
sql> WHERE F . numfou = P . numfou
sql> AND nomfou = f1 ;

17
++
| NB_PROD |
++
| 2 |
++

Pour connatre le nombre de produits proposs, cest dire dont le numprod a une occurence dans la table PROPOSER,
on procde de la faon suivante :
sql> SELECT COUNT(DISTINCT numprod ) AS NB_PRODUITS_PROPOSES
sql> FROM PROPOSER ;

++
| NB_PRODUITS_PROPOSES |
++
| 3 |
++

Le DISTINCT nous sert viter quun mme produit propos par des fournisseurs diffrents soit comptabilis
plusieurs fois.

1.5.2 Groupage
Linstruction GROUP BY
Les oprations dagrgation considres jusqu maintenant portent sur la totalit des lignes retournes par les
requtes, linstruction GROUP BY permet de former des paquets lintrieur desquels les donnes seront agrges. Cette
instruction sutilise de la manire suivante
sql> SELECT . . .
sql> FROM . . .
sql> WHERE. . .
sql> GROUP BY <liste_colonnes>
sql> ORDER BY . . .

La liste des colonnes sert de critre pour rpartir les lignes dans des paquets de lignes. Si par exemple nous
souhaitons afficher la liste des nombres de produits proposs par chaque fournisseur :
sql> SELECT nomfou , COUNT( ) AS NB_PRODUITS_PROPOSES
sql> FROM FOURNISSEUR F , PROPOSER P
sql> WHERE F . numfou = P . numfou
sql> GROUP BY nomfou ;

+++
| nomfou | NB_PRODUITS_PROPOSES |
+++
| f1 | 2 |
| f2 | 1 |
| f3 | 1 |
+++

Linstruction HAVING
Supposons que de la requte prcdente, nous ne souhaitions garder que les lignes pour lesquelles la valeur
NB_PRODUITS_PROPOSES est gale 1. Ajouter une condition dans WHERE serait inutile, le filtrage occasionn par
WHERE est effectu avant lagrgation. Il nous faudrait une instruction pour ninclure que des groupes de donnes
rpondant certains critres. Linstruction utilise pour ce faire est HAVING. Son utilisation est la suivante :

18
sql> SELECT . . .
sql> FROM . . .
sql> WHERE . . .
sql> GROUP BY. . .
sql> HAVING <condition>
sql> ORDER BY . . .

Par exemple,
sql> SELECT nomfou , COUNT( numprod ) AS NB_PRODUITS_PROPOSES
sql> FROM FOURNISSEUR F , PROPOSER P
sql> WHERE F . numfou = P . numfou
sql> GROUP BY nomfou
sql> HAVING COUNT( numprod ) = 1
sql> ORDER BY nomfou DESC;

+++
| nomfou | NB_PRODUITS_PROPOSES |
+++
| f3 | 1 |
| f2 | 1 |
+++

Affichons les noms des fournisseurs qui ont livr strictement plus dun produit diffrent (toutes livraisons confon-
dues),
sql> SELECT nomfou
sql> FROM FOURNISSEUR F , DETAILLIVRAISON D
sql> WHERE F . numfou = D . numfou
sql> GROUP BY F . numfou , nomfou
sql> HAVING count (DISTINCT numprod ) > 1 ;

++
| nomfou |
++
| f1 |
++

19
1.6 Vues
1.6.1 Dfinition
Une vue est une table contenant des donnes calcules sur celle dune autre table. Les donnes dune vue sont tout
le temps jour. Si vous modifiez les donnes dune des tables sur lesquelles est calcule la vue, alors les modifications
sont automatiquement rpercutes sur la vue.

1.6.2 Syntaxe
Apprciez la simplicit de la syntaxe :
sql> CREATE VIEW <nom_vue> AS <requete>

1.6.3 Application
Par exemple, la requte suivante met en correpondance les noms des produits avec le nombre de fournisseurs qui
le proposent :
sql> SELECT nomprod , COUNT( numfou ) AS NB_FOURNISSEURS
sql> FROM PRODUIT P
sql> LEFT OUTER JOIN PROPOSER PR
sql> ON P . numprod = PR . numprod
sql> GROUP BY nomprod
sql> ORDER BY COUNT( numfou ) ;

+++
| nomprod | NB_FOURNISSEURS |
+++
| Cornichons | 0 |
| Roue de secours | 1 |
| Cotons tiges | 1 |
| Poupee Batman | 2 |
+++

Ce type de requte sera explit dans un cours ultrieur. Pour le moment, notez juste que les outils dont vous
disposez pour le moment ne vous permettront pas de formuler une requte affichant les noms des produits nayant
aucun fournisseur. Crons une vue pour ne pas avoir se farcir la requte chaque fois que nous aurons besoin de ces
informations :
sql> CREATE VIEW NB_FOURNISSEURS_PAR_PRODUIT AS
sql> SELECT nomprod , COUNT( numfou ) AS NB_FOURNISSEURS
sql> FROM PRODUIT P
sql> LEFT OUTER JOIN PROPOSER PR
sql> ON P . numprod = PR . numprod
sql> GROUP BY nomprod
sql> ORDER BY COUNT( numfou ) ;

Une fois cre, on peut interroger une vue de la mme faon quon interroge une table :
sql> SELECT
sql> FROM NB_FOURNISSEURS_PAR_PRODUIT ;

+++
| nomprod | NB_FOURNISSEURS |
+++
| Cornichons | 0 |
| Roue de secours | 1 |
| Cotons tiges | 1 |
| Poupee Batman | 2 |

20
+++

Notez que toute modification dans la table PROPOSER ou PRODUIT sera immdiatement rpercute sur la vue.
sql> INSERT INTO PROPOSER VALUES ( 3 , 4 , 9 ) ;
sql> SELECT
sql> FROM NB_FOURNISSEURS_PAR_PRODUIT ;

+++
| nomprod | NB_FOURNISSEURS |
+++
| Cotons tiges | 1 |
| Cornichons | 1 |
| Roue de secours | 1 |
| Poupee Batman | 2 |
+++

Maintenant, nous souhaitons voir safficher, pour tout i, le nombre de produits proposs par exactement i fournis-
seurs.
sql> SELECT CONCAT ( Il y a , COUNT( ) , produit (s) qui est / sont propos (s) par ,
sql> NB_FOURNISSEURS , fournisseur (s). )
sql> AS NOMBRE_DE_FOURNISSEURS
sql> FROM NB_FOURNISSEURS_PAR_PRODUIT
sql> GROUP BY NB_FOURNISSEURS
sql> ORDER BY NB_FOURNISSEURS ;

++
| NOMBRE_DE_FOURNISSEURS |
++
| Il y a 3 produit ( s ) qui est / sont propos ( s ) par 1 fournisseur ( s ) . |
| Il y a 1 produit ( s ) qui est / sont propos ( s ) par 2 fournisseur ( s ) . |
++

1.6.4 Suppression
On supprime une vue avec linstruction suivante :
sql> DROP VIEW <nom_vue >;

21
1.7 Requtes imbriques
Oracle permet dimbriquer les requtes, cest--dire de placer des requtes dans les requtes. Une requte imbrique
peut renvoyer trois types de rsultats :
une valeur scalaire
une colonne
une table

1.7.1 Sous requtes renvoyant une valeur scalaire


Le rsultat dune requte est dit scalaire sil comporte une seule ligne et une seule colonne. Par exemple :
sql> SELECT COUNT( ) FROM PRODUIT

++
| COUNT( ) |
++
| 4 |
++

On peut placer dans une requte une sous-requte calculant un rsultat scalaire. Un tel type de sous-requte se place
soit comme une colonne supplmentaire, soit comme une valeur servant valuer des conditions (WHERE ou HAVING).

Colonne fictive
On peut ajouter une colonne dans une requte, et choisir comme valeurs pour cette colonne le rsultat dune
requte. Ce type de requte est souvent une alternative GROUP BY. Par exemple, la requte suivante nous renvoie,
pour tout produit, le nombre de fournisseurs proposant ce produit :
sql> SELECT nomprod , (SELECT COUNT( )
sql> FROM PROPOSER PR
sql> WHERE PR . numprod = P . numprod ) AS NB_FOURNISSEURS
sql> FROM PRODUIT P

+++
| nomprod | NB_FOURNISSEURS |
+++
| Roue de secours | 1 |
| Poupee Batman | 2 |
| Cotons tiges | 1 |
| Cornichons | 1 |
+++

Conditions complexes
On peut construire une condition en utilisant le rsultat dune requte. Pour notre exemple, dclarons dabord une
vue contenant le nombre darticles proposs par chaque fournisseur,
sql> CREATE VIEW NB_PROD_PAR_FOU AS
sql> SELECT numfou , (SELECT COUNT( )
sql> FROM PROPOSER P
sql> WHERE P . numfou = F . numfou ) AS NB_PROD
sql> FROM FOURNISSEUR F

Ensuite, recherchons les noms des fournisseurs proposant le plus de produits :


sql> SELECT nomfou
sql> FROM FOURNISSEUR F , NB_PROD_PAR_FOU N
sql> WHERE F . numfou = N . numfou

22
sql> AND NB_PROD = (SELECT MAX( NB_PROD )
sql> FROM NB_PROD_PAR_FOU )

++
| nomfou |
++
| f1 |
| f3 |
++

La requte SELECT MAX(NB_PROD) FROM NB_PROD_PAR_FOU est value avant, et son rsultat lui est substitu dans
lexpression de la requte. Comme on a
sql> SELECT MAX( NB_PROD ) FROM NB_PROD_PAR_FOU ;

++
| MAX( NB_PROD ) |
++
| 2 |
++

Alors la requte prcdente, dans ce contexte, est quivalente


sql> SELECT nomfou
sql> FROM FOURNISSEUR F , NB_PROD_PAR_FOU N
sql> WHERE F . numfou = N . numfou
sql> AND NB_PROD = 2

++
| nomfou |
++
| f1 |
| f3 |
++

INSERT et UPDATE
On peut placer dans des instructions de mises jour ou dinsertions des requtes imbriques. Par exemple,
sql> INSERT INTO PERSONNE ( numpers , nom , prenom )
sql> VALUES ( (SELECT MAX( numpers ) + 1 FROM PERSONNE ) ,
sql> Darth , Vador ) ;

1.7.2 Sous requtes renvoyant une colonne


On considre une colonne comme une liste de valeurs, on peut tester lappartance dun lment cette liste laide
de loprateur IN. On peut sen servir comme une alternative aux jointures, par exemple, rcrivons la requte de la
section prcdente. La requte suivante nous renvoie le nombre de produits proposs par les fournisseurs proposant le
plus de produits :
sql> SELECT MAX( NB_PROD ) FROM NB_PROD_PAR_FOU

++
| MAX( NB_PROD ) |
++
| 2 |
++

Maintenant, recherchons les numros des fournisseurs proposant un tel nombre de produits :

23
sql> SELECT N . numfou
sql> FROM NB_PROD_PAR_FOU N
sql> WHERE NB_PROD = (SELECT MAX( NB_PROD )
sql> FROM NB_PROD_PAR_FOU )

++
| numfou |
++
| 1 |
| 3 |
++

Notons que sil existe plusieurs fournisseurs proposant 2 produits, cette requte renverra plusieurs lignes. Cest
donc par hasard quelle ne retourne quune ligne. Le numro du fournisseur proposant le plus de produits est donc le
1. Cherchons ce fournisseur :
sql> SELECT nomfou
sql> FROM FOURNISSEUR F
sql> WHERE F . numfou IN ( 1 )

++
| nomfou |
++
| f1 |
++

Il suffit donc dans la requte ci-dessous de remplacer le 1 par la requte qui a retourn 1. On a finalement :
sql> SELECT nomfou
sql> FROM FOURNISSEUR F
sql> WHERE F . numfou IN (SELECT N . numfou
sql> FROM NB_PROD_PAR_FOU N
sql> WHERE NB_PROD = (SELECT MAX( NB_PROD )
sql> FROM NB_PROD_PAR_FOU ) )

++
| nomfou |
++
| f1 |
| f3 |
++

1.7.3 Sous requtes non correles renvoyant une table


On peut remplacer le nom dune table dans la clause FROM par une sous-requte. Par exemple, la requte suivante
renvoie une table.
SQL> SELECT
2 (SELECT COUNT( )
3 FROM PROPOSER PR
4 WHERE PR . numfou = F . numfou
5 ) AS NB_PROD
6 FROM FOURNISSEUR F ;

NB_PROD

2
1
1

24
0

Cette table contient, pour chaque fournisseur, le nombre de produits proposs. Si lon souhaite connatre le plus
grand nombre de produits proposs, on se sert du rsultat de la requte ci-dessus comme dune table :
SQL> SELECT MAX( NB_PROD ) AS MAX_NB_PROD
2 FROM
3 (SELECT
4 (SELECT COUNT( )
5 FROM PROPOSER PR
6 WHERE PR . numfou = F . numfou
7 ) AS NB_PROD
8 FROM FOURNISSEUR F
9 );

MAX_NB_PROD

Ce type de requte est une alternative aux vues. Rcuprons maintenant les noms des fournisseurs proposant le
plus de produits (sans jointure et sans vue !) :
SQL> SELECT nomfou
2 FROM FOURNISSEUR
3 WHERE numfou IN
4 (SELECT numfou
5 FROM
6 (SELECT numfou ,
7 (SELECT COUNT( )
8 FROM PROPOSER PR
9 WHERE PR . numfou = F . numfou
10 ) AS NB_PROD
11 FROM FOURNISSEUR F
12 ) N
13 WHERE NB_PROD =
14 (SELECT MAX( NB_PROD )
15 FROM
16 (SELECT numfou ,
17 (SELECT COUNT( )
18 FROM PROPOSER PR
19 WHERE PR . numfou = F . numfou
20 ) AS NB_PROD
21 FROM FOURNISSEUR F
22 ) N
23 )
24 );

NOMFOU

f1

Vous constatez que la solution utilisant les vues est nettement plus simple.

1.7.4 Sous requtes correles


Une sous-requte peut tre de deux types :
simple : Elle value avant la requte principale
correle : Elle est value pour chaque ligne de la requte principale
Par exemple, la requte suivante renvoie le nombre de produits livrs pour chaque fournisseur. Elle contient une
sous-requte correle.

25
SQL> SELECT numfou ,
2 (SELECT SUM( qte )
3 FROM DETAILLIVRAISON D
4 WHERE D . numfou = F . numfou
5 ) NB_PROD_L
6 FROM FOURNISSEUR F ;

NUMFOU NB_PROD_L

1 45
2
3 10
4

Cette mme requte, une fois value, peut server de requte non correle si on souhaite connatre les noms de ces
fournisseurs :
SQL> SELECT nomfou , NB_PROD_L
2 FROM FOURNISSEUR F ,
3 (SELECT numfou ,
4 (SELECT SUM( qte )
5 FROM DETAILLIVRAISON D
6 WHERE D . numfou = F . numfou
7 ) NB_PROD_L
8 FROM FOURNISSEUR F
9 ) L
10 WHERE F . numfou = L . numfou ;

NOMFOU NB_PROD_L

f1 45
f2
f3 10
f4

Amusons-nous : quel sont, pour chaque fournisseur, les produits qui ont t les plus livrs ?
SQL> SELECT nomfou , nomprod
2 FROM FOURNISSEUR F , PRODUIT P ,
3 (SELECT FF . numfou , PP . numprod
4 FROM FOURNISSEUR FF , PRODUIT PP
5 WHERE
6 (SELECT SUM( qte )
7 FROM DETAILLIVRAISON L
8 WHERE L . numfou = FF . numfou
9 AND L . numprod = PP . numprod
10 )
11 =
12 (SELECT MAX( NB_PROD_L )
13 FROM
14 (SELECT numfou , SUM( qte ) AS NB_PROD_L
15 FROM DETAILLIVRAISON L
16 GROUP BY numprod , numfou
17 ) Q
18 WHERE Q . numfou = FF . numfou
19 )
20 GROUP BY numfou , numprod
21 ) M
22 WHERE M . numprod = P . numprod
23 AND M . numfou = F . numfou ;

26
NOMFOU NOMPROD

f1 Roue de secours
f3 Cotons tiges

Dans la requte prcdente, quelles sous-requtes sont correles et lesquelles ne le sont pas ?

27
1.8 Procdures stockes
1.8.1 Exemple
tant donnes la base de donnes de [.11]. Nous comptons implmenter les contraintes suivantes.
Un exemplaire non empruntable ne peut pas tre emprunt.
Un exemplaire ne peut pas tre en possession de deux adhrents la fois.
Un adhrent ne peut pas tre en possession de deux exemplaires diffrents dun mme ouvrage.
Un adhrent ne peut pas emprunter si son abonnement nest pas jour.
Un adhrent ne peut pas tre en possession de plus de cinq livres.
Une mme personne ne peut pas tre la fois catalogue comme auteur et adhrent.
Toutes ces contraintes ne sont pas dclaratives, ce qui signifie quil est impossible dans le create table de les prendre
en compte.
Comment faire ?

1.8.2 SQL Procdural


Le SQL procdural est une extension imprative de SQL. Elle permet dexcuter des instructions lintrieur du
serveur de base de donnes. Par exemple,
delimiter $$

drop procedure compteARebours ;

create procedure compteARebours ( i integer )


begin
declare j integer ;
if i >= 0 then
set j = i ;
while j >= 0 do
select j ;
set j = j 1 ;
end while ;
end if ;
end ;

call compteARebours ( 3 ) ;
$$

delimiter ;

1.8.3 Procdures
Il est possible de stocker des procdures de la mme faon que dans les langages impratifs.
delimiter $$

drop procedure insertAdherent ;


create procedure insertAdherent ( nom varchar ( 6 4 ) , prenom varchar ( 6 4 ) , mail varchar ( 6 4 ) )
begin
i n s e r t into personne ( nompers , prenompers ) values ( nom , prenom ) ;
i n s e r t into adherent ( numpers , mailadherent ) values ( last_insert_id ( ) , mail ) ;
end
$$

call insertAdherent ( Morflegroin , Marcel , marcel@morflegroin . com ) ;


call insertAdherent ( Le Ballon , Gg , gege . m@grosbuveur . com ) ;
call insertAdherent ( Couledru , Gertrude , g. proflechettes@ligue - flechettes . fr ) ;

28
$$

delimiter ;

i n s e r t into personne ( nompers , prenompers ) values ( Rowlings , J. K. ) ;

delimiter $$

drop procedure insertOuvrage ;


create procedure insertOuvrage ( titre varchar ( 6 4 ) , numAuteur integer , nombreExemplaires
integer )
begin
declare ouvrage_inserted_id integer ;
declare i integer ;
i n s e r t into ouvrage ( numauteur , titreouvrage ) values ( numAuteur , titre ) ;
set ouvrage_inserted_id = last_insert_id ( ) ;
set i = 1 ;
while i <= nombreExemplaires do
i n s e r t into exemplaire ( numOuvrage , numExemplaire ) values ( ouvrage_inserted_id
, i) ;
set i = i + 1 ;
end while ;
end
$$

delimiter ;

call insertOuvrage ( Harry Potter and the Deathly Hallows , 4 , 1 0 ) ;

1.8.4 Curseurs
Un curseur permet de parcourir une une les lignes rsultant dun SELECT.
delimiter $$

DROP PROCEDURE IF EXISTS AfficheUtilisateurs ;


CREATE PROCEDURE AfficheUtilisateurs ( )
BEGIN
DECLARE num_pers integer ;
DECLARE nom_pers varchar ( 6 4 ) ;
DECLARE prenom_pers varchar ( 6 4 ) ;
DECLARE nb_a integer ;
DECLARE finished boolean DEFAULT FALSE;
DECLARE personnes CURSOR FOR SELECT numpers , nompers , prenompers FROM personne ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = TRUE;

OPEN personnes ;
personnesloop : LOOP
FETCH personnes INTO num_pers , nom_pers , prenom_pers ;
IF finished THEN
LEAVE personnesloop ;
END IF ;
SELECT COUNT( ) INTO nb_a FROM adherent WHERE numpers = num_pers ;
IF nb_a > 0 THEN
s e l e c t concat ( prenom_pers , , nom_pers , est un adherent ) ;
ELSE
s e l e c t concat ( prenom_pers , , nom_pers , est un auteur ) ;
END IF ;
END LOOP ;

29
CLOSE personnes ;
END;
$$

CALL AfficheUtilisateurs ( ) ;
$$

delimiter ;

1.8.5 Triggers
Un trigger est une procdure stocke de dclenchant automatiquement la suite dun vnement.
delimiter $$

drop t r i g g e r if e x i s t s adherentBeforeInsert ;
create t r i g g e r adherentBeforeInsert before i n s e r t on adherent for each row
begin
declare nb_aut integer ;
declare error_msg varchar ( 1 2 8 ) ;
/ Met l a d a t e s y s t me par d f a u t /
if new . daterenouvellement is null then
set new . daterenouvellement = now ( ) ;
end if ;
/ V r i f i e que l adh r e n t n e s t pas d j un a u t e u r /
s e l e c t count ( ) into nb_aut
from ouvrage
where new . numpers = numauteur ;
if nb_aut > 0 then
set error_msg = concat ( L\ adh rent , new . numpers , est d j un auteur . );
signal sqlstate 45000 set message_text = error_msg ;
end if ;
end ;
$$

delimiter ;

30
.1 Scripts de cration de tables
.2 Livraisons Sans contraintes
Attention : Le numro de livraison est une cl secondaire, cest--dire un numro unique tant donn un fournisseur.
drop table PRODUIT ;
drop table FOURNISSEUR ;
drop table PROPOSER ;
drop table LIVRAISON ;
drop table DETAILLIVRAISON ;

CREATE TABLE PRODUIT


( numprod integer ,
nomprod varchar ( 3 0 ) ) ;

CREATE TABLE FOURNISSEUR


( numfou integer ,
nomfou varchar ( 3 0 ) ) ;

CREATE TABLE PROPOSER


( numfou integer ,
numprod integer ,
prix real ) ;

CREATE TABLE LIVRAISON


( numfou integer ,
numli integer ,
dateli date
);

CREATE TABLE DETAILLIVRAISON


( numfou integer ,
numli integer ,
numprod integer ,
qte integer ) ;

.3 Modules et prerequis
les modules sont rpertoris dans une table, et les modules pr-requis pour sy inscrire (avec la note minimale) se
trouvent dans la table prerequis. Une ligne de la table PREREQUIS nous indique que pour sinscrire dans le module
numro numMod, il faut avoir eu au moins noteMin au module numModPrereq.
DROP TABLE IF EXISTS RESULTAT ;
DROP TABLE IF EXISTS EXAMEN ;
DROP TABLE IF EXISTS PREREQUIS ;
DROP TABLE IF EXISTS INSCRIPTION ;
DROP TABLE IF EXISTS MODULE ;
DROP TABLE IF EXISTS ETUDIANT ;

CREATE TABLE ETUDIANT


( numEtud i n t PRIMARY KEY,
nom varchar ( 4 0 ) ,
prenom varchar ( 4 0 ) ,
datenaiss date ,
civilite varchar ( 4 ) ,
patronyme varchar ( 4 0 ) ,
numsecu varchar ( 1 5 ) NOT NULL

31
);

CREATE TABLE MODULE


( numMod i n t PRIMARY KEY,
nomMod varchar ( 1 5 ) ,
effecMax i n t DEFAULT 30
);

CREATE TABLE EXAMEN


( numMod i n t REFERENCES MODULE ( numMod ) ,
numExam int ,
dateExam date ,
PRIMARY KEY( numMod , numExam )
);

CREATE TABLE INSCRIPTION


( numEtud i n t REFERENCES ETUDIANT ( numEtud ) ,
numMod i n t REFERENCES MODULE ( numMod ) ,
dateInsc date ,
PRIMARY KEY( numEtud , numMod )
);

CREATE TABLE PREREQUIS


( numMod i n t REFERENCES MODULE ( numMod ) ,
numModPrereq i n t REFERENCES MODULE ( numMod ) ,
noteMin i n t NOT NULL DEFAULT 1 0 ,
PRIMARY KEY( numMod , numModPrereq )
);

CREATE TABLE RESULTAT


( numMod int ,
numExam int ,
numEtud int ,
note int ,
PRIMARY KEY( numMod , numExam , numEtud ) ,
FOREIGN KEY ( numMod , numExam ) REFERENCES EXAMEN ( numMod , numExam ) ,
FOREIGN KEY ( numEtud , numMod ) REFERENCES INSCRIPTION ( numEtud , numMod )
);

INSERT INTO MODULE ( numMod , nomMod ) VALUES


( 1 , Oracle ) ,
( 2 , C ++ ) ,
( 3 , C ) ,
( 4 , Algo ) ,
( 5 , Merise ) ,
( 6 , PL / SQL Oracle ) ,
( 7 , mySQL ) ,
( 8 , Algo avancee ) ;

INSERT INTO PREREQUIS ( numMod , numModPrereq ) VALUES


(1 , 5) ,
(2 , 3) ,
(6 , 5) ,
(8 , 5) ,
(7 , 5) ;
INSERT INTO PREREQUIS VALUES ( 6 , 1 , 1 2 ) ;

32
.4 Gomtrie
La table INTERVALLE contient des intervalles spcifis par leurs bornes infrieure et suprieure. Supprimer de la
table intervalle tous les intervalles qui nen sont pas avec une seule instruction.
drop table if e x i s t s RECTANGLE ;
drop table if e x i s t s INTERVALLE ;

CREATE TABLE INTERVALLE


( borneInf int ,
borneSup int ,
PRIMARY KEY ( borneInf , borneSup ) ) ;

CREATE TABLE RECTANGLE


( xHautGauche int ,
yHautGauche int ,
xBasDroit int ,
yBasDroit int ,
PRIMARY KEY ( xHautGauche , yHautGauche , xBasDroit , yBasDroit ) ) ;

INSERT INTO INTERVALLE VALUES (2 , 56) ;


INSERT INTO INTERVALLE VALUES (12 , 30) ;
INSERT INTO INTERVALLE VALUES (2 , 3) ;
INSERT INTO INTERVALLE VALUES (12 , 3) ;
INSERT INTO INTERVALLE VALUES (8 , 27) ;
INSERT INTO INTERVALLE VALUES (34 , 26) ;
INSERT INTO INTERVALLE VALUES (5 , 10) ;
INSERT INTO INTERVALLE VALUES (7 , 32) ;
INSERT INTO INTERVALLE VALUES (0 , 30) ;
INSERT INTO INTERVALLE VALUES (21 , 8) ;

INSERT INTO RECTANGLE VALUES (2 , 12 , 5 , 7) ;


INSERT INTO RECTANGLE VALUES (2 , 12 , 1 , 13) ;
INSERT INTO RECTANGLE VALUES (10 , 13 , 1 , 11) ;
INSERT INTO RECTANGLE VALUES (10 , 13 , 10 , 11) ;
INSERT INTO RECTANGLE VALUES (2 , 7 , 5 , 13) ;
INSERT INTO RECTANGLE VALUES (21 , 73 , 15 , 22) ;
INSERT INTO RECTANGLE VALUES (1 , 2 , 3 , 4) ;
INSERT INTO RECTANGLE VALUES (1 , 5 , 3 , 2) ;
INSERT INTO RECTANGLE VALUES (1 , 6 , 3 , 6) ;
INSERT INTO RECTANGLE VALUES (4 , 2 , 1 , 4) ;
INSERT INTO RECTANGLE VALUES (2 , 3 , 4 , 0) ;
INSERT INTO RECTANGLE VALUES (5 , 4 , 2 , 1) ;

.5 Livraisons
drop table if exists DETAILLIVRAISON ;
drop table if exists LIVRAISON ;
drop table if exists PROPOSER ;
drop table if exists FOURNISSEUR ;
drop table if exists PRODUIT ;

CREATE TABLE PRODUIT


( numprod int ,
nomprod varchar ( 3 0 ) ) ;

CREATE TABLE FOURNISSEUR


( numfou int ,

33
nomfou varchar ( 3 0 ) ) ;

CREATE TABLE PROPOSER


( numfou int ,
numprod int ,
prix i n t NOT NULL) ;

CREATE TABLE LIVRAISON


( numfou int ,
numli int ,
dateli date
);

CREATE TABLE DETAILLIVRAISON


( numfou int ,
numli int ,
numprod int ,
qte i n t NOT NULL) ;

a l t e r table PRODUIT add constraint pk_produit


PRIMARY KEY ( numprod ) ;
a l t e r table FOURNISSEUR add constraint pk_fournisseur
PRIMARY KEY ( numfou ) ;
a l t e r table PROPOSER add constraint pk_proposer
PRIMARY KEY ( numfou , numprod ) ;
a l t e r table LIVRAISON add constraint pk_livraison
PRIMARY KEY ( numfou , numli ) ;
a l t e r table DETAILLIVRAISON add constraint pk_detail_livraison
PRIMARY KEY ( numfou , numli , numprod ) ;
a l t e r table PROPOSER add constraint fk_proposer_fournisseur
FOREIGN KEY ( numfou ) REFERENCES FOURNISSEUR ( numfou ) ;
a l t e r table PROPOSER add constraint fk_proposer_produit
FOREIGN KEY ( numprod ) REFERENCES PRODUIT ( numprod ) ;
a l t e r table LIVRAISON add constraint fk_livraison
FOREIGN KEY ( numfou ) REFERENCES FOURNISSEUR ( numfou ) ;
a l t e r table DETAILLIVRAISON add constraint fk_detail_livraison
FOREIGN KEY ( numfou , numli ) REFERENCES LIVRAISON ( numfou , numli ) ;
a l t e r table DETAILLIVRAISON add constraint fk_detail_livraison_proposer
FOREIGN KEY ( numfou , numprod ) REFERENCES PROPOSER ( numfou , numprod ) ;

INSERT INTO PRODUIT values ( 1 , Roue de secours ) ,


( 2 , Poupee Batman ) ,
( 3 , Cotons tiges ) ,
( 4 , Cornichons ) ;

INSERT INTO FOURNISSEUR values ( 1 , f1 ) ,


( 2 , f2 ) ,
( 3 , f3 ) ,
( 4 , f4 ) ;

INSERT INTO PROPOSER values ( 1 , 1 , 2 0 0 ) ,


(1 , 2 , 15) ,
(2 , 2 , 1) ,
(3 , 3 , 2) ;

INSERT INTO LIVRAISON values ( 1 , 1 , now ( ) ) ,


( 1 , 2 , now ( ) ) ,
( 3 , 1 , now ( ) ) ;

34
INSERT INTO DETAILLIVRAISON values ( 3 , 1 , 3 , 1 0 ) ,
(1 , 1 , 1 , 25) ,
(1 , 1 , 2 , 20) ,
(1 , 2 , 1 , 15) ,
(1 , 2 , 2 , 17) ;

.6 Arbre gnalogique
La table PERSONNE, le champ pere contient le numro du pre de la personne, le champ mere contient le numro
de la mre de la personne.
DROP TABLE IF EXISTS personne ;

CREATE TABLE personne


( numpers i n t PRIMARY KEY,
nom varchar ( 3 0 ) ,
prenom varchar ( 3 0 ) ,
pere int ,
mere int ,
FOREIGN KEY ( pere ) REFERENCES personne ( numpers ) ,
FOREIGN KEY ( mere ) REFERENCES personne ( numpers )
);

insert into personne values ( 1 , Estermont , Cassana , NULL, NULL) ;


insert into personne values ( 2 , Baratheon , Steffon , NULL, NULL) ;
insert into personne values ( 3 , Baratheon , Renly , 2 , 1 ) ;
insert into personne values ( 4 , Baratheon , Stannis , 2 , 1 ) ;
insert into personne values ( 5 , Baratheon , Robert , 2 , 1 ) ;
insert into personne values ( 1 2 , Lannister , Joanna , NULL, NULL) ;
insert into personne values ( 1 3 , Lannister , Tywin , NULL, NULL) ;
insert into personne values ( 9 , Lannister , Cersei , 1 3 , 1 2 ) ;
insert into personne values ( 6 , NULL, Gendry , 5 , NULL) ;
insert into personne values ( 8 , Baratheon , Tommen , 5 , 9 ) ;
insert into personne values ( 7 , Baratheon , Joffrey , 5 , 9 ) ;
insert into personne values ( 1 0 , Baratheon , Myrcella , 5 , 9 ) ;
insert into personne values ( 1 1 , Lannister , Jaime , 1 3 , 1 2 ) ;
insert into personne values ( 1 4 , Lannister , Tyrion , 1 3 , 1 2 ) ;
insert into personne values ( 1 5 , Florent , Selyse , NULL, NULL) ;
insert into personne values ( 1 6 , Baratheon , Shireen , 4 , 1 5 ) ;

.7 Comptes bancaires
DROP TABLE IF EXISTS OPERATION ;
DROP TABLE IF EXISTS TYPEOPERATION ;
DROP TABLE IF EXISTS COMPTECLIENT ;
DROP TABLE IF EXISTS TYPECCL ;
DROP TABLE IF EXISTS PERSONNEL ;
DROP TABLE IF EXISTS CLIENT ;

CREATE TABLE CLIENT


( numcli i n t primary key auto_increment ,
nomcli varchar ( 3 0 ) ,
prenomcli varchar ( 3 0 ) ,
adresse varchar ( 6 0 ) ,
tel varchar ( 1 0 ) ,
CONSTRAINT ck_telephone CHECK( LENGTH ( tel ) =10)

35
);

CREATE TABLE PERSONNEL


( numpers i n t primary key auto_increment ,
nompers varchar ( 3 0 ) ,
prenompers varchar ( 3 0 ) ,
manager int ,
salaire int ,
CONSTRAINT ck_salaire CHECK( SALAIRE >= 1 2 5 4 . 2 8 )
);

CREATE TABLE TYPECCL


( numtypeccl i n t primary key auto_increment ,
nomtypeccl varchar ( 3 0 )
);

CREATE TABLE COMPTECLIENT


( numcli int ,
numccl int ,
numtypeccl int ,
dateccl date not null ,
numpers int ,
CONSTRAINT pk_compteclient
PRIMARY KEY ( numcli , numccl ) ,
CONSTRAINT fk_ccl_typeccl
FOREIGN KEY ( numtypeccl )
REFERENCES TYPECCL ( numtypeccl ) ,
CONSTRAINT fk_ccl_client
FOREIGN KEY ( numcli )
REFERENCES CLIENT ( numcli ) ,
CONSTRAINT fk_ccl_personnel
FOREIGN KEY ( numpers )
REFERENCES PERSONNEL ( numpers )
);

CREATE TABLE TYPEOPERATION


( numtypeoper i n t primary key auto_increment ,
nomtypeoper varchar ( 3 0 )
);

CREATE TABLE OPERATION


( numcli int ,
numccl int ,
numoper int ,
numtypeoper int ,
dateoper date not null ,
montantoper i n t not null ,
libeloper varchar ( 3 0 ) ,
CONSTRAINT pk_operation
PRIMARY KEY ( numcli , numccl , numoper ) ,
CONSTRAINT fk_oper_ccl
FOREIGN KEY ( numcli , numoper )
REFERENCES COMPTECLIENT ( numcli , numccl ) ,
CONSTRAINT fk_oper_codeoper
FOREIGN KEY ( numtypeoper )
REFERENCES TYPEOPERATION ( numtypeoper ) ,
CONSTRAINT montant_operation
CHECK( montantoper <> 0 )
);

36
INSERT INTO TYPECCL VALUES ( 1 , Compte courant ) ,
( 2 , livret ) ,
( 3 , PEL ) ;

INSERT INTO TYPEOPERATION VALUES ( 1 , dpt esp ces ) ,


(2 , pr l vement ) ,
(3 , virement ) ,
(4 , retrait ) ;

.8 Comptes bancaires avec exceptions


DROP TABLE IF EXISTS OPERATION ;
DROP TABLE IF EXISTS COMPTECLIENT ;
DROP TABLE IF EXISTS TYPECCL ;
DROP TABLE IF EXISTS TYPEOPERATION ;
DROP TABLE IF EXISTS PERSONNEL ;
DROP TABLE IF EXISTS CLIENT ;

CREATE TABLE CLIENT


( numcli int ,
nomcli varchar ( 3 0 ) ,
prenomcli varchar ( 3 0 ) ,
adresse varchar ( 6 0 ) ,
tel varchar ( 1 0 )
);

CREATE TABLE PERSONNEL


( numpers int ,
nompers varchar ( 3 0 ) ,
prenompers varchar ( 3 0 ) ,
manager int ,
salaire i n t
);

CREATE TABLE TYPECCL


( numtypeccl int ,
nomtypeccl varchar ( 3 0 )
);

CREATE TABLE COMPTECLIENT


( numcli int ,
numccl int ,
numtypeccl int ,
dateccl date default sysdate not null ,
numpers i n t
);

CREATE TABLE TYPEOPERATION


( numtypeoper int ,
nomtypeoper varchar ( 3 0 )
);

CREATE TABLE OPERATION


( numcli int ,
numccl int ,
numoper int ,

37
numtypeoper int ,
dateoper date ,
montantoper i n t not null ,
libeloper varchar ( 3 0 )
);

ALTER TABLE CLIENT ADD


(
CONSTRAINT pk_client PRIMARY KEY ( numcli ) ,
CONSTRAINT ck_telephone CHECK( LENGTH ( tel ) =10)
);

ALTER TABLE PERSONNEL ADD


(
CONSTRAINT pk_personnel PRIMARY KEY ( numpers ) ,
CONSTRAINT ck_salaire CHECK( SALAIRE >= 1 2 5 4 . 2 8 )
);

ALTER TABLE TYPECCL ADD


CONSTRAINT pk_typeccl PRIMARY KEY ( numtypeccl ) ;

ALTER TABLE TYPEOPERATION ADD


CONSTRAINT pk_typeoperation PRIMARY KEY ( numtypeoper ) ;

ALTER TABLE COMPTECLIENT ADD


(
CONSTRAINT pk_compteclient
PRIMARY KEY ( numcli , numccl ) ,
CONSTRAINT fk_ccl_typeccl
FOREIGN KEY ( numtypeccl )
REFERENCES TYPECCL ( numtypeccl ) ,
CONSTRAINT fk_ccl_client
FOREIGN KEY ( numcli )
REFERENCES CLIENT ( numcli ) ,
CONSTRAINT fk_ccl_personnel
FOREIGN KEY ( numpers )
REFERENCES PERSONNEL ( numpers )
);

ALTER TABLE OPERATION ADD


(
CONSTRAINT pk_operation
PRIMARY KEY ( numcli , numccl , numoper ) ,
CONSTRAINT fk_oper_ccl
FOREIGN KEY ( numcli , numoper )
REFERENCES COMPTECLIENT ( numcli , numccl ) ,
CONSTRAINT fk_oper_codeoper
FOREIGN KEY ( numtypeoper )
REFERENCES typeoperation ( numtypeoper ) ,
CONSTRAINT montant_operation
CHECK( montantoper <> 0 AND montantoper >= 1000 AND montantoper <= 1 0 0 0 )
);

INSERT INTO TYPECCL VALUES (


(SELECT nvl (MAX( numtypeccl ) , 0 ) + 1
FROM TYPECCL
),
Compte courant ) ;

38
INSERT INTO TYPECCL VALUES (
(SELECT nvl (MAX( numtypeccl ) , 0 ) + 1
FROM TYPECCL
),
livret ) ;

INSERT INTO TYPECCL VALUES (


(SELECT nvl (MAX( numtypeccl ) , 0 ) + 1
FROM TYPECCL
),
PEL ) ;

INSERT INTO TYPEOPERATION VALUES (


(SELECT nvl (MAX( numtypeoper ) , 0 ) + 1
FROM TYPEOPERATION
),
dpt esp ces ) ;

INSERT INTO TYPEOPERATION VALUES (


(SELECT nvl (MAX( numtypeoper ) , 0 ) + 1
FROM TYPEOPERATION
),
pr l vement ) ;

INSERT INTO TYPEOPERATION VALUES (


(SELECT nvl (MAX( numtypeoper ) , 0 ) + 1
FROM TYPEOPERATION
),
virement ) ;

INSERT INTO TYPEOPERATION VALUES (


(SELECT nvl (MAX( numtypeoper ) , 0 ) + 1
FROM TYPEOPERATION
),
retrait ) ;

.9 Secrtariat pdagogique
DROP TABLE IF EXISTS RESULTAT ;
DROP TABLE IF EXISTS EXAMEN ;
DROP TABLE IF EXISTS PREREQUIS ;
DROP TABLE IF EXISTS INSCRIPTION ;
DROP TABLE IF EXISTS MODULE ;
DROP TABLE IF EXISTS ETUDIANT ;

CREATE TABLE ETUDIANT


( numEtud i n t PRIMARY KEY,
nom varchar ( 4 0 ) ,
prenom varchar ( 4 0 ) ,
datenaiss date ,
civilite varchar ( 4 ) ,
patronyme varchar ( 4 0 ) ,
numsecu varchar ( 1 5 ) NOT NULL
);

CREATE TABLE MODULE


( numMod i n t PRIMARY KEY,

39
nomMod varchar ( 1 5 ) ,
effecMax i n t DEFAULT 30
);

CREATE TABLE EXAMEN


( numMod i n t REFERENCES MODULE ( numMod ) ,
numExam int ,
dateExam date ,
PRIMARY KEY( numMod , numExam )
);

CREATE TABLE INSCRIPTION


( numEtud i n t REFERENCES ETUDIANT ( numEtud ) ,
numMod i n t REFERENCES MODULE ( numMod ) ,
dateInsc date ,
PRIMARY KEY( numEtud , numMod )
);

CREATE TABLE PREREQUIS


( numMod i n t REFERENCES MODULE ( numMod ) ,
numModPrereq i n t REFERENCES MODULE ( numMod ) ,
noteMin i n t NOT NULL DEFAULT 1 0 ,
PRIMARY KEY( numMod , numModPrereq )
);

CREATE TABLE RESULTAT


( numMod int ,
numExam int ,
numEtud int ,
note int ,
PRIMARY KEY( numMod , numExam , numEtud ) ,
FOREIGN KEY ( numMod , numExam ) REFERENCES EXAMEN ( numMod , numExam ) ,
FOREIGN KEY ( numEtud , numMod ) REFERENCES INSCRIPTION ( numEtud , numMod )
);

INSERT INTO MODULE ( numMod , nomMod ) VALUES


( 1 , Oracle ) ,
( 2 , C ++ ) ,
( 3 , C ) ,
( 4 , Algo ) ,
( 5 , Merise ) ,
( 6 , PL / SQL Oracle ) ,
( 7 , mySQL ) ,
( 8 , Algo avancee ) ;

INSERT INTO PREREQUIS ( numMod , numModPrereq ) VALUES


(1 , 5) ,
(2 , 3) ,
(6 , 5) ,
(8 , 5) ,
(7 , 5) ;
INSERT INTO PREREQUIS VALUES ( 6 , 1 , 1 2 ) ;

.10 Mariages
CREATE TABLE PERSONNE
( numpers number PRIMARY KEY,

40
nom varchar ( 3 0 ) NOT NULL,
prenom varchar ( 3 0 ) ,
pere REFERENCES PERSONNE ( numpers ) ,
mere REFERENCES PERSONNE ( numpers )
);

CREATE TABLE MARIAGE


(
nummari NUMBER REFERENCES PERSONNE ( numpers ) ,
numfemme NUMBER REFERENCES PERSONNE ( numpers ) ,
datemariage DATE DEFAULT SYSDATE ,
datedivorce DATE DEFAULT NULL,
PRIMARY KEY( nummari , numfemme , dateMariage )
);

.11 Bibliothque
Personne

- numPers : int
- nomPers : String
Ouvrage
- prenomPers : String
- numOuvrage : String
- titre : String

-auteur
0..1
-ouvrages * -ouvrage
Adherent
* Exemplaire
Auteur
- mailAdherent : String
- numExemplaire : int
- dateRenouvellement : Date

-emprunts

* -adherents Disponible

Emprunter * -emprunts
- dateEmprunt : Date -exemplaires
- dateRetour : Date

drop table emprunter ;


drop table exemplaire ;
drop table ouvrage ;
drop table adherent ;
drop table personne ;

create table personne


(
numpers i n t primary key auto_increment ,
nompers varchar ( 6 4 ) ,
prenompers varchar ( 6 4 )
);

41
create table adherent
(
numpers i n t primary key ,
mailadherent varchar ( 6 4 ) ,
daterenouvellement date ,
foreign key ( numpers ) references personne ( numpers )
);

create table ouvrage


(
numouvrage i n t primary key auto_increment ,
numauteur int ,
titreouvrage varchar ( 6 4 ) ,
foreign key ( numauteur ) references personne ( numpers )
);

create table exemplaire


(
numouvrage int ,
numexemplaire int ,
empruntable boolean default true ,
primary key ( numouvrage , numexemplaire ) ,
foreign key ( numouvrage ) references ouvrage ( numouvrage )
);

create table emprunter


(
numadherent int ,
numouvrage int ,
numexemplaire int ,
dateemprunt date ,
dateretour date default null ,
primary key ( numadherent , numouvrage , numexemplaire , dateemprunt ) ,
foreign key ( numadherent ) references adherent ( numpers ) ,
foreign key ( numouvrage , numexemplaire ) references exemplaire ( numouvrage , numexemplaire ) ,
check ( dateemprunt < dateretour )
);

drop view adherents ;


create view adherents as
s e l e c t p . numpers , nompers , prenompers , mailadherent
from adherent a , personne p
where p . numpers = a . numpers ;

drop view auteurs ;


create view auteurs as
select
from personne
where numpers not in
( s e l e c t numpers
from adherent
);

drop view exemplaires ;


create view exemplaires as
s e l e c t o . numouvrage , numexemplaire , titreouvrage , concat ( nompers , " , " , prenompers )
as auteur
from personne p , ouvrage o , exemplaire e
where p . numpers = o . numauteur

42
and o . numouvrage = e . numouvrage ;

43