Vous êtes sur la page 1sur 47

Jean Armand YOMBI en homage à Julien SCHNNEL

table à un fichier avec des enregistrements (ou fiches ou articles)


structurés en champs.
INTRODUCTION Nous étudions d’abord le langage sous l’angle manipulation de
données, en commençant par la commande SELECT (permettant
d’exprimer des requêtes d’interrogatrion) qui occupe une place
En 1970 E.F. Codd a posé les fondations du modèle relationnel dans
importante dans ce document.
un article intitulé « A relational model for large Shared Data
Ensuite, nous continuons avec les primitives de mises à jour
Banks » (Communications of the ACM) .
(INSERT, UPDATE et DELETE) et deux commandes de contrôle
La voie était ouverte pour une nouvelle génération de langages
(COMMIT et ROLLBACK).
d’accès aux bases de données, de nature ensembliste (langage
Puis nous passons en revue les commandes de définition et contrôle
algébrique) ou prédicative (logique).
des données (CREATE TABLE, INDEX, VIEW, GRANT,
REVOKE).
Le langage SEQUEL (Chamberlin) a été initialement développé
pour le prototype relationnel SYSTEM-R peaufiné par IBM dans ses
Ces différentes commandes peuvent être utilisées de manière
laboratoires de recherche à San José (milieu des années 70).
interactive ou être intégrées dans un programme d’application écrit
SEQUEL est dérivé du langage SQUARE (Boyce), qui utilisait des
dans un langage traditionnel (le produit PRO*C d’Oracle, par
notations mathématiques et d’aspect plus abstrait.
exremple, permet d’intégrer des instructions SQL dans un
programme écrit en C).
SEQUEL est l’acronyme de Structured English as a Query
Language.
Dans cette U.V. (unité de valeur), nous découvrons les possibilités
SQL est l’évolution commercialisé par IBM du langage SEQUEL. Il du langage au travers de l’outil SQL*Plus (sous Windows) du
a été retenu comme standard officiel (pour les bases de données S.G.B.D. (Système de gestion de bases de données) Oracle
relationnelles) par l’ANSI en 1986. (version 8).
Parallèlement à l’apprentissage du langage, nous faisons la
C’est un langage de manipulation, définition et contrôle de bases connaissance, en cours et en travaux dirigés, du modèle relationnel
de données relationnelles, qui ne requiert pas de connaissance et des opérateurs associés (algèbre relationnelle).
technique particulière en informatique. C’est pourquoi, je présente en annexe la formulation en algèbre
Une base de données relationnelle est perçue par l’utilisateur relationnelle de certains des exemples SQL. Les lecteurs intéressés
comme un ensemble de tables. peuvent y jeter un œil.
Une table est un ensemble non ordonné de lignes. On peut aussi
comparer (si on a une idée de ce qu’est un système de fichiers) une

1
Jean Armand YOMBI en homage à Julien SCHNNEL

Dans la suite du document, nous utilisons les symboles


suivants pour présenter la syntaxe d’une commande : REQUETES
… pour indiquer une répétition possible de D’INTERROGATION
l’argument
[ option ] argument facultatif
[ option1| option2|… ] argument facultatif, pouvant prendre les Toutes les opérations de consultation de données sont réalisées avec
valeurs option1 ou option2 ; l’option la commande SELECT.
soulignée est prise par défaut Toute requête digne de ce nom comporte au moins les clauses
{ option1|option2… } obligatoirement l’une des options SELECT et FROM.
indiquées
SELECT [ ALL DISTINCT ]
Les MOTS RESERVES du langage sont écrits en majuscules. { [ objet. ] * expression [ c_alias ] }
[ , {objet. * expression [ c_alias ] } ]…
Les exemples d’instructions SQL sont présentés dans une police FROM [ user. ] objet [ t_alias ] [ , [ user.] objet [ t_alias] ]…
de caractères différente (courier). [WHERE Condition ]
[ GROUP BY expression [ , expression ] … ]
[ HAVING ConditionGroupe ]
[ { UNION INTERSECT MINUS } Requête ]
[ ORDER BY { expression position } [ ASC DESC]
[ , { expression position } [ ASC DESC] ]…]
[ FOR UPDATE OF colonne [ , colonne ] … ] ;

Un objet est une table ou une vue (les vues seront abordées plus
tard ; pour l’instant, tous nos exemples se rapportent à des tables).

Une expression peut être :

. Une colonne, éventuellement précédée du nom de la table


(table.colonne)

2
Jean Armand YOMBI en homage à Julien SCHNNEL

. Une expression calculée avec des opérateurs et/ou des empno : numéro identifiant un employé
mgr : numéro du responsable (manager) direct d’un employé
fonctions appliquées à une ou plusieurs colonnes.
ename : nom d’employé
sal : salaire
Le symbole * signifie : toutes les colonnes d’une table. Si plusieurs
comm : commissions perçues (uniqsuement pour les vendeurs, les
tables sont citées dans la clause FROM, il faut préfixer le symbole
représentants)
par un nom de table (table.*).
hiredate : date d’embauche
deptno : numéro identifiant un département
t_alias est un alias (synonyme local à la requête) pour un nom de
dname : nom du département (ex : Research)
table.
loc : localisation (la ville)
c_alias permet d’associer un libellé à une expression. Ce libellé sera
utilisé pour la ligne d’entête qu’affiche à l’écran une requête SQL
(par défaut, ce sont les noms des expressions ou colonnes citées dans la clause
Premiers exemples de requêtes :
SELECT qui sont affichés).
STYLE 1 :
La clause HAVING ne peut être présente que s’il y a
aussi la clause GROUP BY. select * from emp ; affiche la table complète des employés

select ename, sal


Voici la Base de données qui nous sert d’exemple : from emp requête avec restriction (sal > 3000)
where sal > 3000 ; et projection (sur les colonnes ename
emp(empno, mgr , ename, job, comm, deptno, hiredate) et sal)

dept(deptno,dname,loc) STYLE 2 (avec utilisation d’alias)


select e.* from emp e ;
emp : les employés
dept : les départements (au sens de services) select e.ename, e.sal
deptno de emp référence deptno de dept from emp e
mgr de emp référence empno de emp where e.sal > 3000 ;

Exercice 1 : Demander aux étudiants de construire le diagramme Par la suite, nous employerons l’un ou l’autre style
entité-relation de cette base.
select ename «Nom»,sal «Salaire» from emp ;

3
Jean Armand YOMBI en homage à Julien SCHNNEL

La ligne d’entête affichée (avant les lignes du résultat) comportera Argument1 opérateur argument2
les libéllés Nom et Salaire au lieu de, respectivement, ename et
sal. Opérateur (de comparaison) : = != <> < <= > >=
Argument1, argument2 peuvent être des:
select job requête affichant les jobs des - constantes
employés - noms de colonnes
from emp ; si plusieurs employés ont le même job, - expressions avec des opérateurs (+, -, /, *)
celui-ci sera affiché plusieurs fois et/ou des fonctions appliquées à une (ou plusieurs)
colonne(s)
select distinct job les doublons sont ôtés (voir plus loin Expressions & fonctions)
from emp ;
De plus, argument2 peut être une requête SQL
select distinct e.ename, e.job (voir Requête Imbriquée)
from emp e ; donne une seule occurrence des (SELECT …)
employés qui ont même nom et même il est alors interprêté comme étant le résultat de cette requête.
job
colonne IS [NOT] NULL
exemple : s’il y a plusieurs (Dupont, détective), la
valeur (Dupont, détective) n’est affichée qu’une fois ; argument [NOT] IN (liste)
donc, si l’on est intéressé de savoir qu’il existe où liste est une suite de valeurs séparées par le symbole,
plusieurs, faire attention !
argument [NOT] IN (SELECT …)
• La clause WHERE (argument, argument, …) [NOT] IN (SELECT …)
Elle est suivie d’une condition, qui peut être combinée avec d’autres argument [NOT] BETWEEN valeur AND valeur
conditions en utilisant les opérateurs logiques AND et OR
argument [NOT] LIKE ‘chaîne générique’
Une condition simple ou composée peut être inversée avec
l’opérateur NOT (…). Dans la chîne (générique), le symbole % désigne toute chaîne de
caractères (y compris, la chaîne vide) et le symbole _ remplace un
Une condition peut avoir l’une des formes suivantes : caractère quelconque.

4
Jean Armand YOMBI en homage à Julien SCHNNEL

Dans les 5 dernières formes citées, argument peut être : select ename, sal + comm “Gains”
from emp
- un nom de colonne where comm is not null ;
- une expression (avec opérateurs de calcul, et/ou
fonctions) comm is not null signifie : « dont la rubrique comm est
renseignée »
Exemples
A propos de cet exemple, il faut absolument bien comprendre la
Requête donnant le nom, n° du responsable et salaire des employés distinction que fait Oracle entre la valeur null et le nombre 0.
dont le nom commence par la lettre S et dont le salaire n’est pas Un employé avec comm = 0 sera affiché par la requête ; en effet, la
compris entre 800 et 2000 (dollars). valeur de comm est connue (elle est égale à 0 !) => comm ≠ null
select el.ename, el.mgr, el.sal • La clause ORDER BY
from emp el
where el.ename like ‘S%’
Elle permet de trier les résultats suivant différentes expressions
and el.sal not between 800 and 2000 ;
(souvent, des noms de colonnes) par ordre croissant (ASC) ou
décroissant (DESC).
les opérateurs like et = ne sont pas équivalents ; la La première expression de la liste est le critère (de tri) primaire.
condition where ename=‘S%’ retiendrait les L’option ASC est prise par défaut pour chacune des expressions
employés qui s’appellent S% ! citées (voir syntaxe d’une requête SQL).
select d.dname Exemples
from dept d
where d.loc in (‘CHICAGO’,‘DALLAS’); Lister les employés par salaires décroissants.
Est équivalent à :
select d.dname from dept d select ename, sal
where d.loc =‘CHICAGO’or d.loc = ‘DALLAS’);
from emp
order by sal desc ;
Si on souhaite rechercher les gains commerciaux (c’est à dire les
employés qui perçoivent des commisions), on écrit:

5
Jean Armand YOMBI en homage à Julien SCHNNEL

Afficher les employés par N° de département décroissant (critère La sous-requête est évaluée en premier et délivre la liste des N° des
principal) et salaire croissant (critère secondaire pour départager départements localisés à Chicago. Puis, la requête principale affiche
les employés du même département). les employés dont le N° de département appartient à cette liste.

select * Quels sont les employés qui occupent le même poste que
from emp l’employé 1 ?
order by deptno desc, sal ;
select *
from emp
• Requêtes imbriquées where job = (select job
from emp
Dans la clause WHERE, les opérateurs = et IN peuvent être suivis where empno = 1) ;
d’une requête SELECT. On dit que celle-ci est imbriquée dans la
requête principale. Différence entre les opérateurs IN et =

Exemples Dans le premeir exemple, il faut obligatoirement (si on ne veut pas


s’exposer aux foudres de l’interprète SQL…) utiliser l’opérateur IN,
Chercher tous les employés qui sont en poste à Chicago. car plusieurs départements (comptabilité, recherche,…) peuvent être
situés à CHICAGO. Donc, il est possible que la sous-requête
Le problème qui se pose est qu’on ne connaît pas directement dans retourne plusieurs lignes.
la table emp dans quelle ville travaille un employé. Il faut d’abord Dans le second exemple, un seul job correspond à l’employé 1
trouver les N° des départements qui sont localisés à Chicago (en (puisque l’attribut empno est l’identifiant). Donc, l’opérateur =
consultant la table dept). convient (mais rien n’interdit d’utiliser IN).

select e.* Quels sont les employés qui ne travaillent pas dans un département
from emp e de recherche ?
where e.deptno in ( select d.deptno
from dept d select *
where d.loc =‘CHICAGO’) ; from emp
where deptno not in (select deptno
from dept
where dname=‘Research’);

6
Jean Armand YOMBI en homage à Julien SCHNNEL

La sous-requête renvoie les n° des départements de recherche • Expressions et Fonctions


(supposés sauvegardés dans une liste L) ; un employé est retenu si
son N° de département est différent de toutes les valeurs de cette Elles sont utilisables dans les clauses SELECT, WHERE, HAVING
liste L. et ORDER BY.

• Si la sous-requête retourne plusieurs colonnes, il faut que la Les opérateurs arithmétiques : +, -, *, /


clause WHERE dans la requête principale mentionne le
même nombre de colonnes. select truc.ename, truc.sal + truc.comm
from emp truc
Exemple : where truc.comm is not null
and truc.comm > 0.25 * truc.sal
Quels sont les employés qui occupent le même poste et ont le même order by truc.sal + truc.comm desc ;
salaire que CLINTON du département 1 ?

select * Les fonctions arithmétiques


from emp
where (job,salaire)in (select job, salaire ABS (n) valeur absolue
from emp CEIL (n) le plus petit entier qui depasse n
where ename = CLINTON
FLOOR (n) le plus grand entier inférieur à n
and deptno = 1) ;
MOD (m,n) reste de la division de m par n
POWER (m,n) m est élévé à la puissance n
Exemple avec plusieurs niveaux d’imbrication
ROUND (n [, m] ) n est arrondi à m décimales (m=0 si omis)
select dname from dept TRUNC (n [, m] ) n est tronqué à m décimales (m=0 si omis)
where deptno in (select deptno from emp SQRT (n) racine carrée
where job=(select job from emp LEAST (n1, n2,…) la plus faible valeur parmi n1, n1, …
where empno = 66 GREATEST (n1, n2, …) la plus forte forte valeur parmi n1, n2, …
) ;
Exemples

Question: quel est le résultat select ename, greatest (sal, comm) from emp ;
délivré par cette requête ?

7
Jean Armand YOMBI en homage à Julien SCHNNEL

select empno,ename,least(round(sal),round(comm)) LEAST (d1, d2), GREATEST (d1, d2)


from emp ADD_MONTHS (d, n) ajoute n mois à date d et renvoie une
where round (sal) > 2000 ; date
MONTHS_BETWEEN (d1, d2) exprime la différence de
mois entre d1 et d2
Les fonctions sur les chaînes de caractères NEXT _ DAY (d, jour) donne la première date qui suit la
date d et qui correspond au jour de la semaine donné.
LENGTH (c) longueur de la chaîne next_day (d, ‘LUNDI’)
UPPER (c) , LOWER (c) conversion en majuscules, minuscules
INITCAP (c) 1ère lettre en majuscule, le reste en SYSDATE est une variable donnant la date système (la date
Minuscules courante).
SUBSTR (c, p [ ,I ] ) extrait la sous-chaîne de c à partir du
p-ème caractère, ayant pour longueur I select * from emp
(jusqu’à fin de chaîne, si I est omis) where sysdate-hiredate < 30 ;
GREATEST (c1, c2,…)
LEAST (c1, c2,…) elle peut être affichée par:
C1 C2 concatène les chaînes C1 et C2 select sysdate
from dual ;

Dual est une sorte de table (prédéfinie) qu’on emploie


Les fonctions sur les dates pour avoir des informations ne provenant pas des tables
d’utilisateurs (homogénéité dans l’écriture des requêtes).
. Deux dates peuvent être comparées entre elles avec les
opérateurs de comparaison ( <,> …) Autre exemple :
. une date peut être cherchée dans un intervalle (d between select 1+2 from dual ;
d1 and d2) pour calculer et afficher la valeur de 1+2 (!)
. le nombre de jours entre 2 dates peut être obtenu par :
d1 – d2

8
Jean Armand YOMBI en homage à Julien SCHNNEL

Les fonctions de conversion Exemple

Le format par défaut d’une date est : ‘dd/mm/yy’ qui correspond à 2 select ename
chiffres pour le jour, le mois et l’année, ces champs étant séparés par from emp
le symbole / where hiredate =
Par exemple : ‘20/08/93’ to_date (‘01/10/1993’, dd/mm/yyyy’);

équivalent à :
La fonction TO_CHAR (d, format) convertit une dete ou une
expression de type date en une chaîne dont le format est précisé.
select ename
Par exemple : to_char (hiredate,‘dd/MON/yy’) -> fom emp
‘20/AOU/93’ where to_char (hiredate,‘dd/mm/yyyy’) =
To_char (hiredate,‘YYYY/MONTH/dd’)->‘1993/AOUT/20’ ‘01/10/1993’;

On consultera avec profit la documentation Oracle


(SQl * PLUS) si on souhaite connaître tous les formats La fonction TO_NUMBER (c) convertit une chaîne de caractères
disponibles (y a t-il des amateurs ?). numériques en un objet de type numérique.

Exemple • Fonctions d’agrégation

select ename, to_char (hiredate, ‘DD/ MONTH’) Les fonctions


from emp
where to_char (hiredate, ‘YYYY’) = ‘1993’ ; AVG (moyene), COUNT (nombre d’occurrences),

La fonction TO_DATE (c, format) convertit une chaîne signifiant MAX, MIN, SUM (somme), STDDEV (écart type),
une date dont le format est précisé en un objet de type date.
VARIANCE
To_date (‘86/19/07’,‘YY/DD/MM’) retourne la date du
19 juillet 1986. Sont appelées fonctions d’agrégation.

Elles s’appliquent à un ensemble de lignes et renvoient une valeur.

9
Jean Armand YOMBI en homage à Julien SCHNNEL

Dans une requête sans clause GROUP BY, on ne peut pas select count (distinct e.job) compte le nombre de
indiquer après SELECT à la fois des noms de colonnes et from emp e ; valeurs distinctes dans
des fonctions d’agrégation. la colonne job

Ces fonctions ne peuvent figurer qu’après les clauses select sum (sal * 1.1) calcule la somme des
from emp ; salaires majorés de 10%.
SELECT et HAVING.
select avg (sal)
Exemples from emp calcule la moyenne des
where upper (job)=‘ANALYST’ ; salaires des analystes
select min (sal),max(sal),avg (sal)
from emp ;

le plus faible et le plus fort select ename, max(sal) Requête mal construite!
salaire, et la moyenne des from emp ;
salaires
En effet, il a été indiqué précédemment qu’on ne pouvait pas
select count(*) le nombre total d’employés mélanger des colonnes et des fonctions d’agrégation après SELECT
from emp ; dans une requête sans clause GROUP BY.

La requête, qui visualise le nom et le salaire de l’employé avec le


select count(job) plus fort salaire, est :
from emp ;
select ename, sal
compte le nombre de valeurs de la colonne from emp
job (sauf les valeurs nulles), c’est à dire le where sal = (select max(sal) from emp) ;
nombre d’employés dont le job est renseigné.
( il y a éventuellement affichage de plusieurs employés, en cas
select e . count (e . job) d’égalité)
from emp e ; FAUX !! il ne faut pas
Exercice 2 :
préfixer les fonctions
d’agrégation par l’alias quel(s) employé(s) du département 20 a (ont) le salaire le plus
élevé ?
• Le traitement des valeurs nulles

10
Jean Armand YOMBI en homage à Julien SCHNNEL

Les valeurs nulles, c’est à dire non renseignées (=null), sont Par contre, sal+nvl(comm,0) vaut sal(+0) si comm=null
ignorées dans les fonctions d’agrégation. select avg(sal+nvl(comm,0) from emp ;

Ainsi : select avg(comm) from emp ; fournira la moyenne des gains perçus par l’ensemble des employés.
produit la moyenne des commissions des employés qui en perçoivent
effectivement. (ceux avec comm=null ne sont pas considérés dans Autres cas :
le calcul)
select count(*) from emp where comm >= 1000 ;
La fonction NVL(colonne, valeur) permet d’attribuer select count(*) from emp where comm < 1000 ;
temporairement, lors de l’exécution d’une requête, une valeur à une
Si on additionne le nombre d’employés retourné par la première
colonne non renseignée .
requête avec celui calculé par la deuxième, on n’obtient pas le
nombre total d’employés ! : en effet, il manque ceux dont la colonne
Exemple : select avg(nvl(comm,0))
comm est à null, qui ne satisfont à aucune des deux conditions
from emp ;
where.
Si, pour un employé, comm est différent de null, la fonction utilise
Mais les valeurs null peuvent encore réserver d’autres surprises,
la valeur de comm de cet employé, sinon la valeur 0 est prise.
ainsi que le montre la requête suivante :
On a en résultat la moyenne des commisions, tous les employés
confondus.
select *
from emp
Il faut, dans certains cas, être très attentif à la façon
where empno not in ( select mgr
dont sont traitées les valeurs null. from emp) ;
Par exemple, sal+comm vaut null si comm=null ( ∀ la valeur Cette requête est censée (mais est-elle sensée) donner en résultat la liste
de sal) des employés qui ne sont pas responsables d’un employé (rappelons
Donc, la requête que mgr indique pour un employé son supérieur hiérarchique). Or ,
select min(sal+comm) from emp ; la requête répond qu’il n’y a pas d’employé répondant à la
condition ! (no rows selected)
donnera la valeur la plus petite de sal+comm, en ne considérant Quelle en est la cause ? (accrochez-vous…)
que les employés dont la valeur de comm n’est pas à null. Certains employés n’ont pas de supérieur hiérarchique ; leur valeur
de l’attribut mgr est égale à null. Par conséquent, la sous requête

11
Jean Armand YOMBI en homage à Julien SCHNNEL

retourne, non seulement les n° des responsables, mais aussi cette


terrible valeur null. On parle d’équi-jointure si le critère de comparaison est une égalité
(ce qui est le cas le plus fréquent).
L’évaluation de NOT IN est vraie si empno est différent de toutes
les valeurs renvoyées par la sous-requête (et fausse si elle égale à L’ordre dans lequel sont citées les tables dans la clause FROM n’a
l’une de ces valeurs) ; en particulier, empno doit être différent de pas d’importance.
null.
Mais l’opération de comparaison entre empno et null donne un Les colonnes apparaissant dans les clauses SELECT et WHERE
résultat null (=inconnu). doivent être écrites sous la forme NomTable.NomColonne si
L’évaluation de NOT IN n’est donc pas vraie (ni fausse d’ailleurs) plusieurs colonnes (de tables différentes) portent le même nom
mais inconnue (ou indéterminée) ! (deptno de emp et deptno de dept).
D’où le résultat que fournit la requête.
Exemple
Pour remédier à ce problème, il faudrait compléter la requête interne
avec la condition where mgr is not null. Liste des employés en poste à CHICAGO, avec le nom de leur
département.
• Requêtes avec jointures
select emp.* , dname
from emp, dept
Nous sommes déjà capables (grâce à l’utilisation de sous requêtes) where(emp.deptno=dept.deptno)and(loc=CHICAGO);
de comparer les valeurs d’une colonne d’une table avec les valeurs
d’une colonne d’une autre table.
Variante avec alias :
Mais si on veut afficher les valeurs de colonnes issues de 2 ou
plusieurs tables, il est indispensable d’employer une requête de type select e.* , d . dname
jointure. from emp e, dept d
Dans ce cas, on cite les différentes tables dans la clause FROM. where e.deptno = d.deptno and d.loc = CHICAGO ;

La plupart du temps, une requête joignant 2 tables est de la forme : Erreur fréquente : oubli de la condition de jointure !
select emp.* , dname
SELECT colonnes de table1 et table2 from emp, dept ;
FROM table1, table2 Condition de
WHERE colonne de table1=colonne de table2 ; jointure

12
Jean Armand YOMBI en homage à Julien SCHNNEL

ne donnerait pas le résultat escompté ; chaque employé serait joint à dept.deptno) , et qu’on n’obtient pas le département (4, NEW) ;
chaque département (= produit cartésien). en effet, il n’y a pas d’employé affecté au département 4 (on peut,
par exemple, supposer qu’il s’agit d’un département nouvellement
Contrairement à l’équi-jointure théorique (voir cours sur le modèle créé et qu’aucune affectation n’a été faite pour l’instant…).
relationnel), la colonne deptno apparaît 2 fois si on écrit :
• La jointure externe : elle permet d’ajouter au résultat de la
select emp .* , dept.* jointure normale, les lignes d’une table qui n’ont pas de
from emp , dept correspondant dans l’autre table (par exemple, les
where emp.deptno= dept.deptno ; départements sans employé).

Illustation Exemple

EMP DEPT select E.* , D.deptno, D.dname


from emp E , dept D
empno ename Deptno deptno dname loc where E.deptno (+)=D.deptno and D.loc= ‘CHICAGO’ ;
1 BUSH … 1 1 RESEArCH CHICAGO
2 GORE … 1 2 RESEARCH DALLAS Le symbole + signifie: on crée un employé bidon (dont toutes les
3 KENNEDY … 2 3 MAFIA CHICAGO
4 CAPONE … 3 4 NEW CHICAGO
colonnes sont à null) et l’on joint les départements sans employé à
… cet employé.

Résultat :

empno ename … deptno dname


RESULTAT
1 BUSH … 1 RESEARCH
2 GORE … 1 RESEARCH
empno ename … deptno dname 4 CAPONE … 3 MAFIA
- - - 4 NEW
1 BUSH … 1 RESEARCH
2
4
GORE
CAPONE


1
3
RESEARCH
MAFIA
• Cas particulier : l’auto-jointure

Une table peut être jointe à elle-même.


On constate que chaque ligne d’employé est jointe avec la ligne
correspondante dans la table des départements (emp.deptno =

13
Jean Armand YOMBI en homage à Julien SCHNNEL

Exemple : Afficher pour chaque employé son nom, son salaire, le Contrainte : les 2 requêtes doivent avoir le même nombre de
nom de son responsable ainsi que son salaire. (Utilisation d’alias colonnes et les colonnes qui se correspondent deux par deux (col11
indispensable) et col21 par exemple) être de même type (faute de quoi, le résultat
n’a aucun sens).
select E.ename, E.sal , F.ename, F.sal On obtient en résultat :
from emp E , emp F
where E.mgr = F.empno ; . avec l’opérateur UNION : les lignes délivrées par la 1
ème
ère
requête
et celles renvoyées par la 2 requête.

E est un employé et F son responsable . avec l’opérateur INTERSECT : les lignes communes aux deux.
Exemple de requête avec plusieurs jointures : . avec l’opérateur MINUS : les lignes retournées par la 1 requête
ère

Chaque employé est joint avec son département d’affectation et avec qui ne sont pas en résultat de la 2ème.
son responsable ; on affiche son nom et son salaire, le nom du
département correspondant ainsi que le nom de son responsable. A de rares exceptions près, on peut trouver des
expressions équivalentes en utilisant (selon le cas) AND,
select El.ename, El.sal,D.dname,E2.ename OR, IN et NOT IN.
from emp E1 , emp E2 , dept D
where E1.deptno = D.deptno
select * from emp where job= SALESMAN
and El.mgr = E2.empno ; union
select * from emp where deptno in (1,3,5) ;
• Les opérateurs UNION, INTERSECT, MINUS
est équivalent à :
Les arguments de ces opérateurs sont des requêtes SELECT (ou plus
exactement : les ensembles de lignes renvoyées par ces requêtes) select * from emp
une requête where job= SALESMAN or deptno in (1,3,5) ;
SELECT col11, col12,…
FROM table1 Par contre
{ UNION INTERSECT MINUS }
une 2e requête select * from prof_titulaires
SELECT col21, col22,…
FROM table2; union select * from prof_stagiaires ;

ne pourrait pas être exprimée autrement.

14
Jean Armand YOMBI en homage à Julien SCHNNEL

• Les clauses GROUP BY et HAVING empno ename job sal deptno

1 BUSH Salesman 5000 1


La clause GROUP BY permet de partitionner une table en sous 2 GORE Analyst 10000 1
ensembles de lignes, appelés groupes. Chaque groupe formé se 3 KENNEDY Salesman 15000 1
4 CAPONE Analyst 4000 2
composera de lignes ayant la même valeur pour les colonnes
citées dans la clause GROUP BY.
2 groupes sont formés (d’après le critère job):
Dans la clause SELECT on ne peut mentionner que :
le groupe des employés avec job =‘Salesman’ ( )
des fonctions d’agrégation ; celles-ci s’appliquent alors à
chaque groupe
les colonnes définissant le groupe 1 BUSH Salesman 5000 1
3 KENNEDY Salesman 15000 1
La clause HAVING permet de filtrer les groupes qui satisfont un
critère donné.
Le groupe avec job= Analyst ( )
HAVING et WHERE ne sont pas interchangeables !!
2 GORE Analyst 10000 1
4 CAPONE Analyst 4000 2

Exemples La clause SELECT est ensuite appliquée à chacun de ces 2 groupes


et retourne les résultats: (Salesman,2) et (Analyst,2)
• Afficher pour chaque job, le nombre d’employés avec • La moyenne des salaires de chaque département, à
ce job. condition que cette moyenne excède 5000.

select job , count (*) from emp select e.deptno, avg(e.sal)


group by job ; from emp e
group by e.deptno
having avg (e.sal) > 5000 ;

Supposons que la table emp contienne : Il y a formation de 2 groupes : les employés du département 1
(BUSH, GORE, KENNEDY) et ceux du département 2 (CAPONE).

15
Jean Armand YOMBI en homage à Julien SCHNNEL

Le premier groupe (département 1) est retenu, car sa moyenne de select deptno, count(*)
salaires est de 10000, mais le deuxième ne vérifie pas la condition from emp
HAVING (sa moyenne est de 4000). where upper(job) = SALESMAN
and sal+nvl(comm, 0) > 8000
Résultat : (1,10000)
group by deptno
having count(*) > 2 ;
• Le nombre d’employés qui sont dans le même
département et occupent le même job. donnera pour chaque département le nombre de vendeurs dont le
salaire est supérieur à 8000 (à condition qu’il y ait dans le
select deptno , job, count (*)
département plus de 2 vendeurs dont le salaire est supérieur à
from emp
group by deptno, job ; 8000 !).

3 groupes sont constitués: La condition C (where upper(job)=’SALESMAN’ and


BUSH et KENNEDY ont en commun la valeur de deptno (=1) et le sal+nvl(comm,0)>8000) est appliqué en premier; seuls les
même job (Salesman). employés vérifiant cette condition sont ensuite regroupés (par
CAPONE est l’unique représentant du groupe (deptno=2 et deptno). Puis les groupes admettant plus de 2 employés vérifiant la
job=Analyst) et Gore, celui du groupe (deptno=1 et job=Analyst). condition C sont retenus et, finalement, affichés.

La requête affiche : select d.loc, count (*)


(1, Salesman , 2), (1, Analyst, 1) et (2, Analyst, 1) from emp e, dept d
where e.deptno=d.deptno
group by d.loc ;
Evaluation à l’intérieur d’une
affichera pour chaque ville, le nombre d’employés (affectés à un
requête
département de cette ville).
La jointure est effectuée avant le partitionnement.
Les différentes clauses qui composent une requête sont traitées dans
l’ordre suivant :
On peut imbriquer plusieurs fonctions d’agrégation dans
[WHERE] - [GROUP BY] - [HAVING] - [ORDER BY] – SELECT
la clause SELECT
Exemples

La requête

16
Jean Armand YOMBI en homage à Julien SCHNNEL

Evaluation des requêtes imbriquées.


Exemple
En règle générale, une requête imbriquée dans une autre est
select max(avg(sal)) from emp évaluée une fois pour toutes, avant transmission de son
group by job ; résultat à la requête qui l’englobe.

select *
Dans un tel cas, l’évaluation dans la clause SELECT est faite de la from emp
manière suivante, en 2 étapes : where deptno in (select deptno from dept
where loc = CHICAGO);
1) la fonction interne est appliquée à chaque groupe ;
ici : calcul de la moyenne des salaires par job La sous-requête
est indépendante
Une liste est produite en résultat intermédiaire
ici : la liste des moyennes (par job) Dans certains cas toutefois, la sous requête est liée à la
requête principale (on parle aussi de requêtes corrélées) ,
2) la fonction externe est appliquée à la liste obtenue ainsi que le montre l’exemple suivant :
ici : la valeur du maximum dans la liste des moyennes, c’est-
à-dire la meilleure moyenne de salaires. select *
from emp E ←
La requête suivante répond à la question : Quel est le job dont le where sal > ( select avg(sal)
salaire moyen est le meilleur ? from emp
where deptno = E.deptno) ;
select job from emp
group by job Le résultat obtenu : la liste des employés dont le salaire est supérieur
having avg (sal) = (select max (avg (sal)) à la moyenne des salaires de leur département.
from emp
group by job La sous requête n’est pas indépendante ; elle est réévaluée pour
chaque employé (E) sélectionné dans la requête principale et
ce qui revient à dire qu’on veut le job dont le salaire moyen est égal retourne la moyenne des salaires des employés qui sont dans le
au maximum dans la liste des salaires moyens des différents jobs ! même département que cet employé (E).

17
Jean Armand YOMBI en homage à Julien SCHNNEL

Un alias est indispensable (E pour emp)


select * Requête principale Lignes scrutées par la
from emp E sous-requête
where sal > (select avg (sal)
from emp 1 NIXON 8000 1 1 NIXON 8000 1
where deptno = emp.deptno) ; 2 REAGAN 20000 2 3 KENNEDY 10000 1
3 KENNEDY 10000 1 4 FORD 12000 1
ne produirait pas le résultat escompté ! 4 FORD 12000 1
5 BUSH 10000 2
Illustration du fonctionnement de la requête La sous requête calcule la moyenne des salaires des employés du
département 1 (NIXON, KENNEDY et FORD), qui vaut 10000.
select *
from emp E L’employé NIXON n’est pas retenu, puisque son salaire est inférieur
where sal >(select avg (sal) à cette valeur.
from emp where deptno = E.deptno);
Puis, c’est au tour de REAGAN d’être examiné : E.deptno prend
Soient les données : la valeur 2.

empno ename sal deptno Lignes scrutées par la


1 NIXON 8000 1 Requête principale sous-requête
2 REAGAN 20000 2 E
3 KENNEDY 10000 1
4 FORD 12000 1 1 NIXON 8000 1
5 BUSH 10000 2 2 REAGAN 20000 2 2 REAGAN 20000 2
3 KENNEDY 10000 1 5 BUSH 10000 2
E, c’est la ligne courante de la table emp. 4 FORD 12000 1
5 BUSH 10000 2
Dans la requête principale, l’employé NIXON (1ère ligne de la
table) est scruté en premier ; E . deptno est égal à 1.
La sous requête est recalculée et retourne cette fois-ci la valeur
15000; REAGAN vérifie la condition demandée (salaire > 15000) et
sera donc affiché en résultat.
Et ainsi de suite… (à vous de jouer)

L’exemple suivant présente également une sous requête liée :

18
Jean Armand YOMBI en homage à Julien SCHNNEL

select EL .empno , EL . ename Dans cette dernière requête, l’alias D n’est pas indispensable,
from emp EL étant donné que les 2 requêtes n’utilisent pas la même table ;
where exists (select E2 .* on peut aussi écrire :
from emp E2
where E2.mgr = EL.empno) ;
select deptno from dept
where not exists (select * from emp
Sont affichés les employés qui sont responsables d’au moins une where deptno=dept.deptno);
personne.
La clause EXISTS renvoie : Nous conseillons toutefois (autant pour des raisons de clarté que
- la valeur vrai si la sous requête retourne au moins une d’homogénéité) l’usage systématique d’alias pour les requêtes
ligne correlées.
- faux, sinon
Exercices nos résolus
Dans l’exemple, un employé (E1) est retenu s’il existe un employé
(au moins) dont le N° de responsable est le numéro de cet employé 1) Quel résultat fournit la requête suivante ?
(E1).
select * from emp x
pour des raisons d’efficacité, on préférera, lorsque cela est where not exists(select*from emp
possible, l’expression d’une requête sous une forme non where job=X.job and
deptno=X.deptno
corrélée.
and empno !=X.empno)
Par exemple, la requête : 2) Requête (sous forme correlée) donnant le N° et nom des
départements dont tous les employés ont un salaire
select deptno from dept
(rubrique sal) supérieur à 2000. (on considérera qu’un
where deptno not in (select deptno from emp)
département sans employés vérifie la condition énoncée)
Résultat: n° des
départements Indication gratuite : raisonnez en inversant la formulation (les
Est préférable sans employés départements tels qu’il n’existe pas d’employés ayant un
salaire…) !
Question subsidiaire : donnez une solution sans utiliser de
select deptno from dept D
corrélation.
where not exists (select * from emp
where deptno = D.deptno)

19
Jean Armand YOMBI en homage à Julien SCHNNEL

3) Difficile : Pour chaque département, on souhaiterait avoir le


% d’employés (c’est à dire le nombre d’employés du PRIMITIVES DE MISES A JOUR
département par rapport au nombre d’employés total)
DES DONNEES
Ce sont les commandes pour insérer (ajouter) de nouvelles lignes
dans une table, modifier des lignes existantes et en supprimer.
Il existe, de plus, deux commandes permettant de valider ou défaire
les mises à jour effectuées (COMMIT et ROLLBACK). Ces
instructions appartiennent en fait à la catégorie des commandes de
contrôle offertes par le langage, mais je préfère les présenter en
même temps que les instructions de mise à jour.

• INSERT : ajout de lignes

(on suppose, bien entendu, que la structure de la table a été définie).

INSERT INTO objet [ (colonne [,colonne]…) ]


{ VALUES (valeur [, valeur ]…) Requête } ;

objet : table (la plupart du temps) ou vue (créée par la commande


CREATE VIEW)

2 formes sont prévues pour la commande :

. les valeurs sont fournies explicitement (VALUES) et


correspondent dans l’ordre aux colonnes mentionnées ; si aucune
colonne n’est citée dans la clause INTO, cela signifie que toutes les
colonnes de la table (ou de la vue) sont concernées.
Dans cette forme, une seule nouvelle ligne est créée par l’ordre
INSERT.

20
Jean Armand YOMBI en homage à Julien SCHNNEL

les colonnes non mentionnées sont automatiquement mises à null


. les valeurs sont fournies par une requête ; toutes les lignes
(à condition qu’elles n’aient pas été spécifiées not null à la
retournées par la requête sont alors ajoutées à la table. création de la table)
Seules les valeurs des colonnes ayant été déclarées not insert into pas_a_plaindre (nom, métier, paye)
null (commande CREATE TABLE) doivent select ename, job, sal from emp
obligatoirement être fournies ; les autres colonnes sont, par where sal > 30000 ;
défaut, mises à null.
ajoute dans la table pas_a_plaindre, qui doit exister, les nom,
(tous les exemples font référence à des tables) job et salaire des employés vérifiant la condition. Dans la colonne
nom de pas_a_plaindre, on récupère les valeurs de la colonne
dans l’ordre des colonnes ename de emp, etc.
défini lors du create
table, soit : deptno,
dname et loc
Saisie des valeurs de type date
Supposons que l’on ait dans dept, une colonne date-de-création
insert into dept (après loc)
values (3,‘Research’, Dallas);
insert into dept date dans le format
insert into dept (loc,dname,deptno) values (5,‘Sales’,‘Chicago’,’26/02/01’) standard
si on souhaite
values (‘New York’,‘computing’,4); insert into dept
entrer les données
dans un ordre values
différent (5,‘Sales’,‘Chicago’,to_date(02/26/2001’,‘MM/DD/YYYY’))

to_date : interprète la chaîne fournie en 1er argument d’après le


insert into emp format indiqué (2e argument) et la convertit en date.
values
(140,5,‘Reagan’,‘cowboy’,20000,null,10,‘26/02/1994’);
la commision est explicitement mise à null

insert into emp (empno,ename,job,deptno,hiredate)


values
(130,‘bush’,‘pdt’,10,to_date(‘2000/12/25’,‘yyyy/mm/dd’));

21
Jean Armand YOMBI en homage à Julien SCHNNEL

• DELETE : suppression de lignes 2ème forme

DELETE FROM objet UPDATE objet


[WHERE condition]; SET (colonne [,colonne ]…) = (Requête)
[WHERE condition] ;
Comme précédemment, objet est une table ou une vue (pour l’instant,
nous ne connaissons que la notion de table). Dans la 2ème forme, les parenthèses (clauses SET) sont inutiles si
une seule colonne est citée ; le nombre de colonnes retournées par la
La commande permet de supprimer toutes les lignes d’une table ou requête doit être égal au nombre de colonnes mentionnées dans SET.
seulement celles vérifiant la condition, dans la partie condition une La requête ne doit renvoyer qu’une seule ligne.
(ou plusieurs) colonne(s) de la table peut être comparée au résultat
d’une requête. update emp set sal = 1.1 * sal ;
augmente de 10% le salaire de
tous les employés (chouette !)
Exemples tous les employés
sont supprimés… update emp set deptno=1, sal=20000
delete from emp ; where deptno =13 tous les employés du dept
13 sont affectés au
Les départements de département 1, avec un
delete from dept recherche disparaissent salaire de 20000 (lires ou
where dname = ‘Research’ ;
update emp change le salaire de tous les
delete from emp set sal = (select 1.1*avg (sal) analystes en : 1,1 x la
where job = (select job from emp where empno = 13) ; from emp moyenne des salaires des
where job = Analyst) analystes
Il vaut mieux ne pas exercer le where job =‘Analyst’;
même job que l’employé n°13…
update emp set (job,sal)=(select job,sal
from emp where empno=1 ;
• UPDATE : mise à jour de lignes (existantes)
1ère forme On affecte à tous les employés le même
UPDATE objet Job et le même salaire que l’employé 1 (il
Faut espérer que celui-ci est bien payé…
SET colonne = valeur [,colonne = valeur ]…
[WHERE condition] ;

22
Jean Armand YOMBI en homage à Julien SCHNNEL

• Les primitives COMMIT et ROLLBACK Les transactions sont délimitées par les commandes COMMIT et
ROOLBACK.
Elles permettent respectivement de valider (confirmer) ou défaire
(annuler) un ensemble de mises à jour effectuées dans la base. L’exemple le plus célèbre de transaction est celui de la transaction
bancaire. Une opération de virement d’une certaine somme (S) d’un
Le principe (dans une session SQL*Plus) est le suivant : compte vers un autre se décompose en 2 opérations élémentaires :
débiter un compte de la somme S, et créditer l’autre (de la même
somme, de préférence !).
(dernier) commit ou début Il n’est pas cohérent que l’une de ces 2 actions soit éxécutée sans
01 session l’autre.
02
03 La transaction, c’est : créditer un compte + Débiter l’autre compte.
Les 0i sont des opérations commit : valide 01, 02 et 03
de mise à jour (insert, 04 Ce concept de transaction est surtout utile pour la programmation
Delete, Update) 05 d’application utilisant une base de données. Nous nous contentons,
rollback : défait la
séquence 04 et 05
pour notre part, de l’utilisation en mode interactif des commandes
COMMIT et ROLLBACK (on peut, par exemple, simuler une
augmentation de salaire pour les employés d’une certaine catégorie
Actions d’un utilisateur, et voir le nouveau total des salaires qui en résulterait).
dans l’ordre chronologique
COMMIT et ROLLBACK ne concernent que les primitives
Comme on peut le constater, COMMIT valide (=rend définitives) INSERT, DELETE et UPDATE (n’espérez pas récupérer
toutes les mises à jour faites depuis le précédent COMMIT (ou le avec ROLLBACK, par exemple, une table que vous avez
début de la session) et ROLLBACK les annule. détruit par DROP !).
Le concept de transaction . Certaines commandes SQL (CREATE, ALTER, DROP,
GRANT,…) provoquent automatiquement la validation des
Une transation est une séquence atomique d’opérations (générées par Mises à jour faites précédemment.
des ordres SQL) qui fait passer la base d’un état cohérent à un autre . Incidemment, COMMIT et ROLLBACK libèrent aussi les
état cohérent.
différents verrous acquis par la transaction en cours.
Par atomique, on entend que toutes les opérations de mise à jour
Ces verrous peuvent avoir été acquis explicitement
incluses dans la transaction doivent êtres faites, ou aucune (c’est tout
(commande LOCK) ou implicitement : par ex., un UPDATE
ou rien).

23
Jean Armand YOMBI en homage à Julien SCHNNEL

verrouille en écriture les lignes modifiées et empêche un L a figure suivante présente 2 sessions parallèles, où U2 espionne
autre utilisateur de faire un UPDATE portant sur l’une inlassablement U1 (regardez à quel moment les mises à jour faites
d’entre elles. par U1 deviennent visibles à U2).
. Dans le même ordre d’idées, les mises à jour faites par un
utilisateur (disons : U) ne seront visibles à un autre utilisateur
que lorsque U aura confirmé par COMMIT.
. En cas de panne (incident matériel ou logiciel, arrêt anormal
d’un processus utilisateur), une transaction non terminée est
annulée (les mises à jour nos validées par COMMIT sont
perdues).
On peut aussi définir dans une transaction des points de contrôle
(SAVEPOINT) qui peuvent être utilisés pour annuler partiellement
une transaction.
Un savepoint est défini par un identificateur (exemple :
SAVEPOINT S) et la commande ROLLBACK TO S).
On ne peut, par contre, pas valider partiellement une transaction.

A (dernier) commit ou début


01 session
02
03

04
05
B si on fait COMMIT, on valide 01 jusqu’à
05 et le point de contrôle
S est ôté.
si on fait ROOLBACK T annule 04 et 05
et on a encore la possibilité, pour les
Action d’un utilisateur dans opérations 01, 02 et 03. de les valider
l’ordre chronologique ou de les défaire.

24
Jean Armand YOMBI en homage à Julien SCHNNEL

Etat initial
N° d’employé salaire deptno
1 8000 1
LE LANGAGE DE DEFINITION
2 10000 1 ET CONTROLE DES DONNEES
U1 Utilisateurs concurrents U2
update emp (merci pour la contribution de Georges Rosenthal à la rédaction de ce chapitre)
set sal = 1.1 * sal ;
• Gestion des tables
insert into emp
values (3, 12000, 2);
Créer une table (Format élémentaire de création d’une table)
select * from emp ; select * from emp ;
1 8000 1 1 8000 1 CREATE TABLE nom (colonne type [ NULL NOT NULL]
2 11000 1 2 10000 1 [ , colonne type [ NULL NOT NULL ]] …);
3 12000 2
commit
select * from emp La structure de la table est définie en nommant ses différentes
delete from emp where deptno=1 1 8000 1 colonnes, avec leur type; par défaut, les valeurs null sont
2 10000 1 autorisées pour une colonne.
3 12000 2
select * from emp ;
select * from emp ;
Les principaux types autorisés (sous Oracle) sont :
3 12000 2
1 8000 1 . char(n) chaîne de caractères de longueur fixe = n (avec
2 10000 1 n<=255)
3 12000 2
rollback . varchar2(n) chaîne de caractères de longueur variable
( retour à l’état de la table (maximale = n)
après le dernier commit) (varchar est actuellement un synonyme de varchar2)
select * from emp ; select * from emp ; . number entier ou réel
1
2
8000
10000
1
1
1
2
8000
10000
1
1
. number(p) entier (d’au plus p chiffres)
3 12000 2 3 12000 2 . number(p,d) décimal sur p positions en tout (séparateur décimal
compris), dont d chiffres décimaux
Chronologies des actions de U1 Chronologie des actions de U2 . date

25
Jean Armand YOMBI en homage à Julien SCHNNEL

create table service (noservice, ville)


. long chaîne longue (jusqu’à 2 Go) ; restriction : par as select deptno, loc
table, pas plus d’une colonne de type long from dept
where lower(dname)=’research’ ; crée une table service,
On peut aussi utiliser integer, float et decimal dont les colonnes
noservice et ville
CREATE TABLE nom [ (colonne [NOT NULL] ,…) ] héritent resp. des types de
deptno et loc, initialisée
AS Requête ;
avec les départements de
recherche (s’il y en a).
Dans cette 2ème forme, la structure de la table est définie à partir
des colonnes citées dans la requête ; les colonnes de la table créée
héritent des spécifications de type des colonnes de la requête, et Créer une table en spécifiant des contraintes d’intégrité
éventuellement des mêmes noms (dans le cas où on n’indique pas de A partir de
Oracle version 7
nom de colonne pour la nouvelle table).
En outre, la table est initialisée avec les lignes retournées par la
CREATE TABLE Table
requête (si le résultat de celle-ci n’est pas vide).
( {descriptionColonne contrainteTable } [ ,{idem} ] …) ;
On n’évoque pas ici certains paramètres de nature interne
(caractéristiques de stockage) qui peuvent être données à la . descriptionColonne, c’est :
création d’une table (ex. : TableSpace, Cluster ; plutôt du côté nomcolonne type [DEFAULT expression] [ contrainteColonne]
Administrateur).
. contrainteColonne se rapporte à une colonne donnée :
Exemples
Est automatiquement [ NULL NOT NULL ]
create table emp interprété par Oracle [ { UNIQUE PRIMARY KEY } ]
( empno number (8) not null, comme étant le type [ REFERENCES [user.] table [ (colonne) ][ON DELETE CASCADE]]
mgr number (8), ename varchar (20), varchar2 [ CHECK (condition)
job varchar2(10), sal number (8,2),…) ;
Chaque contrainte peut être précédée de la clause CONSTRAINT
L’une des règles du modèle relationnel est que l’attribut identifiant nomContrainte (nom attribué à la contrainte par l’utilisateur).
(la clé) doit avoir une valeur définie pour toutes les lignes de la
table; mais bien entendu, d’autres colonnes que empno peuvent être Plusieurs expressions de contraintes sont possibles pour une colonne
(mais UNIQUE et PRIMARY KEY s’excluent).
déclarées not null (ename, par exemple).

26
Jean Armand YOMBI en homage à Julien SCHNNEL

Plusieurs colonnes de la table peuvent être affublées de la contrainte Je n’ai précisé de nom (salaire) que pour la contrainte
UNIQUE (pas de doublons dans la colonne), mais on ne spécifie relative à sal ; il est recommandé de le faire
qu’une fois PRIMARY KEY (pour l’identifiant). systématiquement.

La clause REFERENCES permet de déclarer une contrainte . contrainteTable : contrainte concernant une ou plusieurs
d’intégrité de référence. colonnes de la table.
Par exemple, toute valeur du champ deptno de la table emp (n° de
département auquel est rattaché un employé) doit exister dans le champ On retrouve, avec une légère nuance dans la syntaxe de
deptno de la table dept (n° des départements existants). REFERENCES, les mêmes clauses (sauf NULL).

Si le nom de colonne n’est pas indiqué pour la table [ { UNIQUE PRIMARY KEY } (colonne [ , colonne]…) ]
reférencée, il s’agit implicitement de la colonne de cette table [ CHECK (condition) ]
qui est déclarée PRIMARY KEY. [ FOREIGN KEY (colonne [ ,colonne]… )
REFERENCES [user.] table [ (colonne [ , colonne ]… ) ]
Create table emp [ ON DELETE CASCADE ] ]
(empno number (8), PRIMARY KEY ,
mgr number (8) , Chaque contrainte peut être précédée de la clause CONSTRAINT
ename varchar2 (20) NOT NULL UNIQUE , nonContrainte.
job varchar2 (20) NOT NULL , FOREIGN KEY signifie clé étrangère ; le groupe de colonnes
sal number (8,2)CONSTRAINT salaire citées (éventuellement une seule) est l’identifiant (PRIMARY KEY)
CHECK(sal between 2000 and 50000),
comm number (8) , d’une autre table.
hiredate date DEFAULT sysdate ,
deptno number (2) REFERENCES dept (deptno) Exemples de contrainteTable :
) ; Contrainte concernant les
2 colonnes job et comm
La contrainte sera vérifiée lors de l’ajout ou de la mise à jour d’un CONSTRAINT commJob CHECK( (comm is not null and job
employé ; en outre, toute suppression de département encore = salesman ) or (comm is null and job !=’Salesman’))
référencé par des employés sera refusée, sauf si la clause ON
DELETE CASCADE est prévue. Dans ce cas la suppression d’un PRIMARY KEY (nhotel, nordre)
département provoque la suppression (en cascade) des employés qui Pour une table de Chambre (d’hôtel) :
Identifiant composé de 2 champs : le N°
en font partie (solution radicale…). d’hôtel et le n° d’ordre (le n° inscrit sur
la porte d’une chambre).

27
Jean Armand YOMBI en homage à Julien SCHNNEL

Considérons à présent qu’on fait des réservations (pour une seule


Ici, toutes les contraintes chambre).
create table emp (autres que not null)
(empno number(8),mgr number(8), sont regroupées après les
create table reservation
ename varchar2 (20) NOT NULL définitions des colonnes ( nreservation number (8) PRIMARY KEY ,
job varchar2 (20) NOT NULL et nommées code_client char (6) NOT NULL REFERENCES client,
sal number(8,2) NOT NULL, comm number(8) , numero_hotel number (4) NOT NULL ,
deptno number (2) , numero_chambre number (2) NOT NULL ,
demande date DEFAULT SYSDATE ,
hiredate date DEFAULT sysdate, debut date NOT NULL , fin date ,
CONSTRAINT c_salaire CHECK (sal between 2000 and 50000) FOREIGN KEY (numero_hotel, numero_chambre) REFERENCES
CONSTRAINT c_commJob chambre
CHECK ( (comm is not null and job = Salesman) or ) ;
( comm is null and job != ‘Salesman) ) ,
CONSTRAINT u_ename UNIQUE (ename),
Créer un type (structuré)
CONSTRAINT pk_emp PRIMARY KEY (empno) ,
Uniquement à partir d’ORACLE 8
CONSTRAINT fk_deptno FOREIGN KEY (deptno)
REFERENCES dept ON DELETE CASCADE
) ; CREATE TYPE type AS OBJET
( { nom-colonne type} [ , { idem } ] …)
référence implicite vers la colonne de la table /
dept définie comme PRIMARY KEY.
create type adresse-t as objet
On constate que l’on peut utiliser pour une (norue number (3), rue varchar (20) ,
contrainteColonne la syntaxe (plus générale) d’une codePostal Char (5), ville varchar (15) )
contrainteTable. /

On peut maintenant créer une table dont une se réfère à ce type


. Un exemple de référence composée (clause FOREIGN KEY) adresse_t
create table chambre create table etudiant
( nhotel number (4) not null REFERENCES hotel,
(code number(4)primary key, adr adresses_t ,…) ;
nordre number (2) not null,
type_chambre char(3) CHECK (type_chambre in(‘IND’,…)),
CONSTRAINT pk_chambre PRIMARY KEY (nhotel, nordre) L’accès au sous-champ rue de la colonne adr est réalisé par la
) ; notation pointée : adr.rue
Toutefois, une requête telle que :

28
Jean Armand YOMBI en homage à Julien SCHNNEL

select code, adr.rue, adr.ville from emp


where adr.codePostal like ‘67 %’ ;
curieusement ne fonctionne pas !
RENAME ancienNom TO nouveauNom ;

Il faut obligatoirement se servir d’un alias : rename emp to salarie


select e.code, e.adr.rue, e.adr.ville
from emp e where e.adr.codePostal like ‘67 %’ ;
rename salarie to emp salarie est le nouveau
nom de la table emp

On peut aussi créer une table (objet-relationnelle) ayant la Ne pas confondre avec CREATE SYNONYM qui donne
structure d’un type par à un objet un nom supplémentaire (alias).
CREATE TABLE nom OF type; Modifier la structure d’une table
create table adresses OF adresse_t ;
ALTER TABLE [utilisateur. ] nomTable
[ADD (colonne type [ NULL NOT NULL ] , …) ]
Supprimer, renommer une table
[MODIFY (colonne [type] [ NULL NOT NULL ] , …) ] ;
DROP TABLE [utilisateur. ] nomTable ;
Avec la clause ADD, on ajoute des colonnes à la structure de la
table ; avec modify, on modifie le type d’une (ou plusieurs) colonne
On ne peut supprimer que les tables qu’on a soi-même créés (sauf si
existante.
on dispose d’un privilège administrateur, auquel cas on peut préciser
devant le nom de la table, le nom de son créateur).
Exemples
drop table emp ;
alter table emp
modify (sal number (10,2) , job varchar2 (30) ) ;

Dans la plupart des cas, on a besoin d’élargir une


colonne.
Si toutefois, on veut diminuer la longueur d’une colonne
ou changer son type (number en char, par ex.), il faut
que toutes les valeurs de cette colonne soient à null ; il
est alors nécessaire de passer par une table intermédiaire

29
Jean Armand YOMBI en homage à Julien SCHNNEL

si on souhaite conserver les actuelles valeurs de la - alter table t add (colonne…) sans indiquer not null
colonne. - Mettre à jour les valeurs dans la colonne (update)
On procède de la manière suivante (soit t le nom de la - alter table t modify (colonne … not null)
table à modifier) :
1) créer une table intermédiaire, avec les Pour supprimer une colonne (par exemple, la colonne budget
nouvelles spécifications de types qu’on vient d’ajouter précédemment) :
2) copier les données de t dans intermédiaire
(insert) 1) create table departement as
3) détruite t (drop) select deptno, dname, loc
from dept ; on omet la colonne budget
4) renommer intermédiaire en t (rename)
alter table emp
2) drop table dept dans la clause Select
3) rename departement to dept
modify (job null)
supprime la spécification not null
pour la colonne job ; les valeurs Réarranger l’ordre des colonnes d’une table, et les renommer
null y sont maintenant autorisées
1) create table service (nom, ville, numero)
as select dname, loc deptno from dept ;
Pour l’opération inverse (contrainte une colonne à not 2) et 3) : même principe que précédemment
null) : pas de problème si la table est vide ; sinon, la
colonne ne doit, évidemment, pas comporter . Pour ajouter ou supprimer des contraintes, on utilise aussi la
actuellement de valeur =null. commande ALTER TABLE.
alter table dept
ALTER TABLE table
add (budget number(6) ) ; ajout de la colonne
budget à la table
[ ADD ( {descriptionColonne contrainteTable }…) ]
dept (toutes les [MODIFY (descriptionColonne …) ]
valeurs de ce champ [DROP contrainte]
sont automatique- [ {ENABLE DISABLE } contrainte ] ;
ment mises à null)
En plus de l’ajout de nouvelles colonnes (avec, éventuellement, des
On ne peut créer un nouveau champ avec l’indication contraintes) à une table et la modification de colonnes existantes, la
not null que lorsque la table est vide ; si tel n’est pas commande offre les possibilités d’ajout de contraintes, de
le cas, procéder en 3 étapes : suppression, (définitive par DROP), d’inhibition de contraintes (mise
hors service provisoire) et d’activation (réactivation).

30
Jean Armand YOMBI en homage à Julien SCHNNEL

Exemples CREATE [ UNIQUE ] INDEX nomIndex ON table (colonne


[ , colonne ] …) ;
alter table emp
modify (ename varchar2 (30) ) Rappel: mgr est le n° de La mention UNIQUE garantit l’unicité des valeurs des colonnes
drop CONSTRAINT c_salaire ; l’employé responsable d’un indexées dans la table.
employé
alter table emp
En Oracle V8/9, il est plutôt recommandé d’utiliser les clauses
add (prime number(4),FOREIGN KEY (mgr) REFERENCES emp); PRIMARY KEY ou UNIQUE lors du CREATE TABLE (les index
sont automatiquement créés).
alter table emp
drop UNIQUE (ename) ; Exemples
la contrainte est
alter table emp inhibée create table emp (empno number (8) not null , …) ;
disable CONSTRAINT commJob ; (provisoirement) +
create unique index Iemp_no on emp (empno) ;
alter table emp
disable PRIMARY KEY ;
mais on préfèrera la solution :
la contrainte est réactivée (entre
temps, on a pu faire des mises
alter table emp a jour pas catholiques)
create table emp
enable PRIMARY KEY ; ( empno number (8) PRIMARY KEY, …)
on peut créer plusieurs index
sur la même table (toutefois,
• Gestion des index ne pas en abuser…)
create index Iempno_deptno on emp (deptno)
Les index (construits sur une table) dans une base de données ont le create index Iempno_job on emp (job) ;
même fonctionnement que les index (ou tables de matières) d’un
quelconque ouvrage ; la consultation de l’index dans l’annuaire des Index sans l’option UNIQUE puisque doublons autorisés
pages jaunes permet de retrouver rapidement un mot-clé (rubrique
professionnelle) avec les pages associées. Ces index sont exploités par l’optimisateur de requêtes (intégré au
S.G.B.D.) pendant une interrogation (SELECT) en fonction de la
Un index accélère (en principe) les requêtes dont la condition de présence de colonnes indexées dans la clause WHERE de la requête.
recherche (clause WHERE) porte sur une colonne indexée. Par exemple, l’index Iemp_deptno sera automatiquement utilisé
par le système pour une requête comme :
Ajout d’un index à une table select * from emp where deptno = 1 ;

31
Jean Armand YOMBI en homage à Julien SCHNNEL

Pour l’utilisateur, l’écriture des requêtes est La clause ORDER BY n’est pas autorisée dans la requête
indépendante des index ! Il est souvent utile d’indexer associée par défaut, la vue hérite des noms de colonne de
les colonnes de jointure (deptno de emp et deptno la requête.
de dept) ; les requêtes joignant 2 tables y gagnent en
performance. Une vue est une table virtuelle (en ce sens qu’elle n’est pas un
récipient de données) définie, grâce à la requête SQL qui lui est
Evitez toutefois de créer des index à tort et à travers ; il associée, à partir des tables, voire d’autres vues.
n’est, par exemple, pas utile d’indexer la colonne job si
80% des employés ont le job de Salesman !! Elle peut être manipulée (avec quelques restrictions toutefois) par les
La colonne doit être discriminante. utilisateurs, comme s’il s’agissait d’une table.

D’un point de vue structure interne : l’index contient une entrée pour La définition de la vue est cataloguée dans le dictionnaire de
chaque valeur de la colonne indexée, et y associe l’adresse de la (les) données ; chaque fois qu’une requête invoque cette vue, Oracle
ligne(s) qui a (ont) cette valeur de la colonne ; il est organisé en arbre accède au dictionnaire pour lancer l’exécution de la requête liée à la
hiérarchisé équilibré (B-Tree). vue.
Cf U.V. de structures
de données Exemple
Suppression d’index create view personnel
as select empno, ename, job, dname, loc
DROP INDEX nomIndex ; from emp, dept
where emp.deptno = dept.deptno ; la définition de personnel
drop index Iemp_deptno ; est stockée dans le
dictionnaire ; la requête
La suppression d’une table provoque la suppression des index select * from personnel ; select ne s’exécute pas !
rattachés à celle-ci.
invoque la vue définie précédemment ; Oracle en recherche la
• Les tables virtuelles, ou vues définition et lance, en réalité, la requête :
Créer une vue
select empno, ename, job, dname, loc
CREATE VIEW nomVue [ (colonne [ ,colonne] … ) ] from emp, dept
AS Requête where emp.deptno = dept.deptno ;
[WITH CHECK OPTION] ;

32
Jean Armand YOMBI en homage à Julien SCHNNEL

. Plus généralement, une requête initiale (R) portant sur une vue est - La commande GRANT, que nous verrons d’ici peu -patience, que
transformée par l’interpréteur en une requête qui est la diable… -permet de donner aux utilisateurs des droits d’accès sur des
combinaison de R et de la requête associée à la vue (tâche parfois tables ou vues ; notez dès à présent que, par défaut, seul le créateur d’un
assez difficile …). objet possède des droits sur celui-ci.
select * from personnel where ename like ‘S%’ ;
devient: Ainsi, la vue personnel masque aux utilisateurs ayant reçu le
droit de consulter personnel (et pas les tables réelles emp et
select empno, ename, job, dname, loc dept) les colonnes sal et comm, entre autres. En outre, les
fom emp, dept
were emp.deptno = dept.deptno and ename like S% ; utilisateurs en question ignorent que les informations proviennent de
2 tables distinctes qui sont jointes lors de la consultation de
select loc, count (*) from personnel personnel.
where lower (job) = ‘salesman’ Ce qui nous amène tout naturellement au 3ème intérêt des vues…
group by loc ;

est tranformée en : renforcent l’indépendance logique

select loc, count (*) from emp, dept Les programmes d’application utilisant des vues sont (en partie)
where emp.deptno = dept.deptno and lower (job) = immunisés contre les modifications de la structure de la base ; si une
‘salesman’ table ou une colonne change de nom, il suffit de faire des retouches
group by loc ; dans les définitions des vues dépendantes.

Intérêt des vues Grâce aux vues, des utilisateurs différents peuvent avoir des visions
différentes de la même base de données (schémas externes) ; les
facilitent l’écriture de requêtes complexes (le problème peut mêmes données peuvent être présentées selon diverses perspectives ;
être décomposé en créant une vue pour une partie de la la vue personnel, par exemple, présente les données des tables
requête). emp et dept sous une forme assemblée.
la gestion de la confidentialité (des données)
La vue qui suit présente une colonne qui est, en réalité, le résultat
C’est la vocation première des vues. d’un calcul :
Une vue permet de cacher à certains utilisateurs des données create view moyennes (num_dept, moysal)
as select e.deptno, avg (e.sal) ,
sensibles ; il suffit, pour cela, de leur autoriser l’accès aux vues, mais
from emp e
pas aux tables réelles. group by e.deptno ; colonne calculée = avg (sal)

33
Jean Armand YOMBI en homage à Julien SCHNNEL

La requête: select num_dept, moysal from moyennes ; A partir de la version 7, il vaut, bien entendu, mieux
déclenchera le calcul de avg (sal) pour chaque département. préciser ces deux contraintes directement dans CREATE
TABLE.
La vérification des contraintes d’intégrité
Mises à jour des tables au travers des vues
Jusqu’à la V6, la création des vues assorties de la mention WITH
CHECK OPTION était le seul moyen de vérifier des contraintes La mise à jour d’une vue (par INSERT, UPDATE, DELETE)
d’intégrité (c’est un devenu un peu obsolète). consiste, en réalité, à mettre à jour la table sur laquelle elle est
La clause WITH CHECH OPTION permet de contrôler et rejeter des définie.
mises à jour ne respectant pas la condition énoncée dans la clause
WHERE (de la requête associée à la vue). Il fallait, par conséquent, Toutefois, la mise à jour d’une vue est soumise aux restrictions
donner aux utilisateurs les droits de mise à jour (insert,…) sur la suivantes :
vue (au lieu de la table réelle).
. la vue doit être définie à partir d’une seule table, et la requête
Exemple de vue de contrainte. associée ne pas comporter de clause GROUP BY, ni la mention
DISTINCT pour une colonne citée dans SELECT.
create view good_emp
as select * from emp . pour utiliser UPDATE ou INSERT, la clause SELECT de la
where deptno in (select deptno from dept) requête associée à la vue ne doit pas mentionner d’expression
and ( job = Salesman or comm is null) calculée comme, par exemple, sal+comm.
with check option ;
Job ≠ ‘Salesman’ comm is null
a b est traduit sous la forme a ou b
. pour que INSERT n’échoue pas, toutes les colonnes de la table
à partir de laquelle la vue est définie) qui ont été déclarées not
null doivent figurer dans la vue.
Les employés créés (ou mis à jour) au travers de la vue good_emp
doivent vérifier les conditions énoncées dans where, c’est à dire : le
L’inconvénient des mises à jour au travers de vues (avec clause With
n° de département doit exister dans la table dept (intégrité de Check Option) réside dans la non convivialité du message d’erreur,
référence) et les employés qui ne sont pas vendeurs ont une suite à la violation de l’une des contraintes (on reçoit en pleine poire
commission à null. quelque chose comme : ORA-1402 : VIEW WITH CHECK
OPTION WHERE-CLAUSE VIOLATION… et débrouillez-vous
avec ça ! ).

34
Jean Armand YOMBI en homage à Julien SCHNNEL

Un autre inconvénient ( plus général) des vues est qu’elles La commande sert aussi bien à créer un nouvel utilisateur (option
ralentissent sensiblement les opérations de consultation et de mise à CONNECT obligatoire + éventuellement RESOURCE et/ou DBA)
jour des données. qu’à étendre des privilèges ou modifier le mot de passe initial.
La seule utilisation possible de la commande pour un utilisateur ne
Supprimer une vue disposant pas du droit DBA (database administrator) est la
modification de son mot de passe.
DROP VIEW nomVue ;
Le privilège (un rôle en fait !) CONNECT autorise un utilisateur à :
La suppression d’une table n’engendre pas automatiquement la
suppression des vues où cette table intervient; il faut faire le ménage . se connecter à la base en appelant l’un des outils Oracle (SQL*
soi-même. Plus, par ex.)
. changer son mot de passe
• La gestion des privilèges
. manipuler les objets (tables, vues) de la base si des droits
On distingue deux catégories de privilèges : les privilèges de type (select,insert, …) lui ont été accordés par les
système (gérés par un administrateur de la base) et les privilèges vis propriétaires des objets.
à vis des objets créés (accordés par les propriétaires de ces objets).
. transmettre des autorisations sur des objets s’il a obtenu le droit
de retransmettre.
Nous nous intéressons essentiellement aux privilèges de type objet,
la première catégorie relevant davantage de l’administration. . créer des vues et des synonymes (nous en parlons d’ici peu ) pour
des objets autorisés.
Les privilèges système
Par exemple, pour pouvoir créer une vue, il faut avoir reçu le droit
En principe réservés aux administrateurs, ils permettent de select sur les tables mises en jeu.
créer/modifier des objets essentiels de la base (tables, profils,
triggers,…). Un tel utilisateur ne peut, par contre, pas créer de table ni d’index.

GRANT { priv-syst rôle } [, {priv-syst rôle } ] … Le rôle RESOURCE autorise un utilisateur à :


TO {utilisateur rôle PUBLIC } [, {utilisateur rôle PUBLIC }]…
[ WITH ADMIN OPTION] ; . créer des tables, index.
WITH ADMIN OPTION : l’utilisateur bénéficiaire peut
. donner des droits de manipulation (ou les reprendre…) sur ses
retransmettre les droits associés à d’autres utilisateurs. propres objets à d’autres utilisateurs.

35
Jean Armand YOMBI en homage à Julien SCHNNEL

Le rôle DBA permet de créer des utilisateurs, de donner (ou retirer) DROP ANY ROLE DROP ANY SEQUENCE
DROP ANY SNAPSHOT DROP ANY SYNONYM
des privilèges aux utilisateurs, d’accéder à tous les objets de base, de
créer des synonymes publics et d’effectuer les opérations de DROP ANY TABLE DROP ANY TRIGGER
maintenance de la base. DROP ANY VIEW DROP PROFILE
DROP PUBLIC DATABASE LINK DROP PUBLIC SYNONYM
DROP ROLLBACK SEGMENT DROP TABLESPACE
Liste des privilèges Système (inutile de les apprendre par cœur) DROP USER
EXECUTE ANY PROCEDURE
ALTER ANY CLUSTER ALTER ANY INDEX FORCE ANY TRANSACTION forcer commit/rollback sur toute transaction
FORCE TRANSACTION
ALTER ANY PROCEDURE ALTER ANY ROLE GRANT ANY PRIVILEGE GRANT ANY ROLE
ALTER ANY SEQUENCE ALTER ANY SNAPSHOT INSERT ANY TABLE LOCK ANY TABLE
ALTER ANY TABLE ALTER ANY TRIGGER MANAGE TABLESPACE mettre online/offline, oubegin/end backup de
ALTER ANY DATABASE ALTER PROFILE tablespace
ALTER RESOURCE COST ALTER ROLLBACK SEGMENT READUP autoriser des requêtes sur des données de
ALTER SESSION ALTER SYSTEM classe supérieure à la classe de la session
ALTER TABLESPACE ALTER USER RESTRICTED SESSION autoriser connexion à une base démarrée en
ANALYZE ANY analyser toute table, tout cluster, tout index RESTRICT
AUDIT ANY auditer tout objet avec les cdes AUDIT SELECT ANY SEQUENCE SELECT ANY TABLE
AUDIT SYSTEM auditer tout le système UNLIMITED TABLESPACE utiliser sans restriction tout tablespace
BACKUP ANY TABLE exporter tout table de tout utilisateur UPDATE ANY TABLE
BECOME USER devenir un autre utilisateur (pour importer une WRITEDOWN opérer sur des objets de classe inférieure
base) WRITE UP opérer sur des objets de classe supérieure
COMMENT ANY TABLE commenter toute table, vue ou colonne
CREATE ANY CLUSTER CREATE ANY INDEX La commande REVOKE permet de supprimer partiellement ou
CREATE ANY PROCEDURE CREATE ANY SEQUENCE totalement des privilèges accordés.
CREATE ANY SNAPSHOT CREATE ANY SYNONYM
CREATE ANY TABLE CREATE ANY TRIGGER
CREATE ANY VIEW REVOKE { priv-syst rôle } [, { priv -syst rôle } ] …
CREATE ANY CLUSTER FROM { utilisateur rôle PUBLIC } [, { utilisateur rôle PUBLIC } ]… ;
CREATE DATABASE LINK CREATE PROCEDURE
CREATE PROFILE CREATE PUBLIC DATABASE LINK Exemples
CREATE PUBLIC SYNONYM CREATE ROLE
CREATE ROLLBACK SEGMENT CREATE SEQUENCE
CREATE SESSION autoriser la connexion à la base grant connect to raffarin identified by ump ;
CREATE SNAPSHOT
CREATE SYNONYM CREATE TABLE création (par un dba nécessairement)
CREATE TABLESPACE CREATE TRIGGER de l’utilisateur raffarin, avec un
CREATE USER CREATE VIEW
DELETE ANY TABLE supprimer des lignes de toute table ou vue mot de passe.
DROP ANY CLUSTER
DROP ANY INDEX DROP ANY PROCEDURE

36
Jean Armand YOMBI en homage à Julien SCHNNEL

grant connect,resource to chirac identified by rpr ; GRANT update (colonne, …) ON table

l’utilisateur chirac a, en plus, la Les privilèges possibles sont les suivants :


possibilité de définir des structures de
tables (et des index,…) Droit Table vue séquence Procédure snapshot
fonction
grant resource to raffarin ; package
ALTER
raffarin jouit à présent des DELETE
mêmes privilèges que chirac
EXECUTIVE
chirac reprend l’avantage
INDEX
grant dba to chirac ; INSERT
REFERENCES
grant connect to chirac identified by elysee ; SELECT
UPDATE
Changement du mot de passe
REFERENCES: permet au bénéficiaire de créer une contrainte
grant create session, create table to redford ; faisant références à la table.
grant create user to redford ; INDEX et REFERENCES ne peuvent être attribués à un rôle.
revoke create user from redford ;
Le créateur d’un objet en est le propriétaire et a naturellement tous
La gestion des privilèges (ou droits) sur les objets
les droits sur celui-ci : SELECT, INSERT, UPDATE, DELETE,
Ils permettent les opérations sur les objets d’un schéma donné. ALTER (pour alter table) et INDEX (pour ajouter des index à
une table).
GRANT {droit [ , droit ]… ALL } [ (colonne [, colonne ]…)] (les privilèges ALTER et INDEX ne s’appliquent pas aux vues).
ON [ utilisateur. ] objet
TO { utilisateur rôle [ , utilisateur rôle ]… PUBLIC } Les autres utilisateurs (hormis les dba) n’ont, par défaut, aucun
[ WITH GRANT OPTION ] ; droit sur les objets des copains.

objet = table ou vue Le propriétaire peut accorder, sélectivement, à d’autres utilisateurs


(tous les utilisateurs = PUBLIC) des privilèges sur ses objets (tous
Pour les droits SELECT, UPDATE et REFERENCES, les privilèges = ALL).
on peut stipuler des colonnes.

37
Jean Armand YOMBI en homage à Julien SCHNNEL

En transmettant un droit avec l’option WITH GRANT OPTION, Quand bien même un utilisateur a bénéficié d’un droit
l’heureux bénéficiaire peut, à son tour, le transmettre à un autre sur un objet, il doit, par défaut, en indiquer le
utilisateur, mais pas à un rôle (rassurez-vous, ce n’est pas contagieux…). propriétaire (en préfixant le nom de l’objet par le nom
du propriétaire.objet).
Exemples
Si, par ex., chirac transmet à juppe le droit select pour une
grant all on emp to jules with grant option ; table de nom cadeau, celui-ci doit écrire : select * from
grant select, update (sal, comm) on emp to jim ; chirac.cadeau ;
Toutefois, ceci peut être évité par l’emploi de synonymes.
. La reprise de droits est ordonnée par la commande REVOKE.
CREATE [PUBLIC ] SYNONYM [utilisateur. ] nomSynonyme
REVOKE { droit [ , droit ] … ALL } FOR [ utilisateur.] Objet ;
ON [ utilisateur. ] objet
FROM { utilisateur rôle [ , utilisateur rôle ]… PUBLIC } ; Si le nom d’utilisateur est omis (dans la clause FOR), l’objet (table
ou vue) doit appartenir à l’utilisateur créant le synonyme.
Revoke insert on emp from dupont ; Seuls les utilisateurs de type DBA sont habilités à définir des
synonymes PUBLIC ; en outre, ils peuvent créer un synonyme pour
La clause FROM PUBLIC reprend les privilèges qui avaient un utilisateur donné (en indiquant son identité avant le nom du
été donnés à PUBLIC (GRANT … TO PUBLIC), mais ne synonyme).
reprend pas les privilèges qui avaient été accordés sur cet objet Les autres utilisateurs ne peuvent créer que des synonymes à usage
individuellement (c’est à dire: en nommant un utilisateur)!! privé.

grant select on dept to durand, dupont; Il y a plusieurs façons de régler le problème de juppe (supposé non
grant select on dept to public ; DBA) :
Tous les utilisateurs
(actuels et futurs) peuvent
lire dept
. l’utilisateur juppe crée lui-même le synonyme
create synonym cadeau for chirac.cadeau ;
revoke select on dept from public ; Dans les 2 cas, le synonyme
est réservé à juppe
durand et dupont conservent
ce droit !! . un utilisateur DBA s’y colle
create synonym juppe.cadeau for chirac.cadeau ;

38
Jean Armand YOMBI en homage à Julien SCHNNEL

create synonym juppe.kdo for chirac.cadeau ; Merci président


grant select(ename,sal),insert,update(sal)
Nom de synonyme on emp
différent du nom de l’objet to public

grant all on dept to karembeu ;


Si chirac fait lui-même le travail, il peut écrire : grant all on emp to karembeu;
implicitement : chirac.cadeau le rêve fut de courte
revoke select on dept from griffith; durée…
create synonym juppe.cadeau for cadeau ;
revoke insert,update on emp from public ;
. le DBA peut aussi être plus généreux :
create public synonym cadeau for chirac.cadeau ; voir exemple : les utilisateurs n’ont plus, sur emp, que le droit
select,karembeu conserve les droits qu’il (elle) a obtenu
Tous les utilisateurs (ayant reçu le droit select sur cadeau) personnellement en
pourront y faire référence par : select * from cadeau ;
revoke delete on dept from karembeu ;
Une erreur (assez fréquente) est de croire que la création
d’un synonyme (PUBLIC notamment) dispense d’accorder des Combinaison de et : karembeu a tous les droits sur dept,
droits ; GRANT est indispensable ! (les synonymes évitent sauf delete.
seulement d’avoir à indiquer le propriétaire de l’objet). …
revoke all on dept from karembeu ; Disgrâce
La suppression d’un synonyme s’effectue par : revoke all on emp from karembeu ;

DROP [PUBLIC] SYNONYM [ utilisateur. ] nomSynonyme; grant select, update


on dept to raffarin
Exemples de transmission (et révocation) de privilèges with grant option ;

Hypothèse : chirac, propriétaire de emp et dept, est aux raffarin bénéficie à présent de privilèges select, update sur
manœuvres dept et de la possiblité de transmettre ceux-ci à d’autres
utilisateurs.
grant select on dept mélanie &richard
to griffith, gere ; raffarin ne se fait pas prier et propage…

39
Jean Armand YOMBI en homage à Julien SCHNNEL

grant select , update on chirac.dept to basinger ; La contrainte (job=’Salesman’ or comm is null) est violée
grant select on chirac.dept to pitt with grant option ;
et sharon stone va devoir faire face au terrible: “ORA-01402:
(comme nous l’avons indiqué précédemment, l’utilisation d’un
VIEW WITH CHECK OPTIO WHERE-CLAUSE VIOLATION” !!
synonyme pour chirac.dept faciliterait la lourde tâche de
raffarin) . Un exemple de vue variable (en fonction de l’identité de
l’utilisateur), accessible en lecture à tout le monde.
grant select, update (sal,comm)
on emp to kidman create view homonymes (nom, deptno, job)
as select ename,eptno,job from emp
create view gains (nom, date_embauche, salaire) where upper(ename)= upper (user); user = nom de l’utilisateur courant
as selecr ename, hiredate, sal from emp
where job= ‘Manager’ ; grant select on homonymes to public ;

grant select on gains to nicholson ; Explication: un utilisateur consultant la vue homonymes verra le nom
(à titre de vérification), le n° de département et le job des employés
Remarque : il est préférable de qui portent le même nom que lui.
Tous les utilisateurs (comptes Oracle) peuvent consulter
. Exemple de vue avec contrainte spécifier les contraintes directement
homonymes ; mais ceux dont le nom ne correspond pas à un nom
lors du CREATE TABLE
create view good_emp d’employé ne verront rien (no rows selected).
as select * from emp
where deptno in (select deptno from dept) Les tables du dictionnaire de données (en réalité, des
and ( job= Salesman or comm is null) vues) sont construites sur ceprincipe.
with check option ; exemple : user_tables, qui done la liste des tables
créées par un utilisateur ; user_tables est une vue
grant select, select, update on good_emp to stone ;
variable.
instructions écrités par
l’utilisateur stone (sharon) Le concept de ROLE

create synonym bon_employe for chirac.good_emp ; Jusqu’à présent, nous n’avons vu que la notion d’utilisateur ; il
insert into bon_employe existe en plus le concept de rôle.
values(66,1,Schnell,PDG,20000,30000,2,’16-JUL-97’);

comm Un rôle est un ensemble nommé de privilèges (système et objet) qui


peut être attribué à des utilisateurs. Il offre une plus grande facilité

40
Jean Armand YOMBI en homage à Julien SCHNNEL

de gestion des droits d’accès aux objetts (voir exemple plus loin pour 2) Maintenant, nous créons et utilisons un rôle :
s’en convaincre).
create role premierMinistre identified by matignon ;
On peut fabriquer un rôle avec la commande :
Donner des droits
grant all on emp to premierMinistre ; à un rôle
CREATE ROLE nomRole grant insert on dept to premierMinistre;
[NOT IDENTIFIED IDENTIFIED BY motDePasse] ; grant select,update on dept to premierMinistre with grant
option ;
(à condition d’avoir le droit de créer des rôles !)
grant premierMinistre to jospin;
La commande GRANT supporte :
revoke premierMinistre from jospin ; Donner un rôle à un utilisateur
. la transmission de privilèges à des utilisateurs (là, nous sommes l’utilisateur hérite des droits
terrain connu…) grant premierMinistre to raffarin attachés rôle premierMinistre

. la transmission de privilèges à des rôles Dans une session, un utilisateur peut activer (interpréter comme au
. l’attribution d’un rôle à un utilisateur cinéma) un rôle donné (à condition de connaître le mot de passe
éventuel de ce rôle).
. l’attribution d’un rôle à un rôle ! (et la bouche est bouclée…)
SET ROLE { rôle [ IDENTIFIED BY mot-de-passe]
Exemples
[ , rôle [ IDENTIFIED BY mot-de-passe] ]…
1) Sans définir de rôle : all [ EXCEPT rôle [, rôle]…] NONE } ;

grant all on emp to jospin ; L’instruction permet aussi de demander l’activation de tous les rôles
grant insert on dept to jospin;
grant select,update on dept to jospin with grant
à l’exception de certains ; on peut également souhaiter ne jouer
option; aucun rôle (dommage…) ou se libérer d’un (ou plusieurs) rôles.
revoke all on emp from jospin;
revoke all on dept from jospin; on donne à raffarin les mêmes La suppression d’un rôle s’effectue par :
droits qu’à jospin (avant qu’on
n’ait enlevé à ce dernier ses droits)
grant all on emp to raffarin ;
DROP ROLE rôle ;
grant insert on dept to raffarin;
grant select,update on dept to raffarin with grant Les rôles système CONNECT, RESOURCE, DBA sont
option; des rôles prédéfinis assurant la comptabilité avec les
privilèges systèmes antérieurs (à la V7).

41
Jean Armand YOMBI en homage à Julien SCHNNEL

EXTERNALLY : le nom de l’utilisateur est identique à celui utilisé pour


Rôles de base Privilèges attachés se connecter au système, préfixé par le paramètre OS_AUTHENT_
CONNECT ALTER SESSION ,CREATE PREFIX du fichier INI.ORA. Le mot-de-passe n’est alors pas requis.
CLUSTER, CREATE Par comptabilité avec la V6, ce paramètre vaut généralement OPS$.
DATABASE LINK, CREATE
Modification d’un utilisateur
SEQUENCE,CREATE
SESSION,CREATE ALTER USER util [IDENTIFIED { BY mot-de-passe EXTERNALLY} ]
SYNONYM, CREATE [ DEFAULT TABLESPACE nom-ts]
TABLE, [TEMPORARY TABLESPACE nom-ts]
CREATE VIEW [ QUOTA { entier [ K M ] UNLIMITED ] ON nom-ts ]..
RESOURCE CREATE CLUSTER, [ PROFILE profil]
[DEFAULT ROLE { Rôle[, rôle].. ALL [ EXCEPT rôle [, rôle] … NONE } ] ;
CREATE PROCEDURE,
CREATE SEQUENCE, Comme on le constate, un rôle par défaut peut être attribué à un
CREATE TABLE, CREATE utilisateur.
TRIGGER
DBA Tous privilèges avec Suppression d’un utilisateur
WITH ADMIN OPTION
EXP_FULL_DATABASE SELECT ANY TABLE, DROP USER util [ CASCADE ] ;
BACKUP ANY TABLE,
INSERT, DELETE, AND CASCADE : supprimer tous les objets contenus dans le schéma de
UPDATE sur les tables util. Option indispensable si le schéma n’est pas vide.
SYS.INCVID, SYS.INCFIL,
Et SYS.INCEXP Nous ne nous appesantissons pas sur ces 3 commandes qui relèvent
IMP_ULL_DATABASE BECOME USER, de l’administration de base de données.
WRITEDOWN

Les utilisateurs

CREATE USER util [ IDENTIFIED { BY mot-de-passe EXTERNALLY } ]


[ DEFAULT TABLESPACE nom-ts]
[TEMPORARY TABLESPACE nom-ts]
[QUOTA { entier [ K M ] UNLIMITED ] ON nom-ts ]..
[PROFILE profil] ;

42
Jean Armand YOMBI en homage à Julien SCHNNEL

Exemple :
Le Dictionnaire de Données USER_TABLES : tables m’appartenant
ALL_TABLES : tables qui me sont accessibles
DBA_TABLES : toutes les tables de la base
Le dictionnaire est un ensemble de tables ou vues qui rassemblent
toutes les informations sur les objets de la base, par exemple : La liste qui suit indique les principales vues ; util peut être remplacé
• Les noms des utilisateurs d’Oracle par l’un des préfixes précédents.
• Les privilèges accordés Sont portés entre parenthèses les noms de colonnes de la vue.
• Les caractéristiques de tous les objets : tables, vues, index,
clusters, synonymes et séquences Remarque : le nom du propriétaire d’un objet (owner) n’est
• Les clés primaires et les clés étrangères évidemment pas cité dans les vues USER_xxxx.
• Les contraintes imposées aux tables
util_CATALOG : liste des tables, vues synonymes et séquences
• Les informations sur les espaces physiques allouées aux
(owner, table_name, table_type)
objets, l’audit (sécurité et performance),…
util_COMMENTS: commentaires associés aux colonnes
(owner, table_name, colum_name, comments)
Le dictionnaire, qui est organisé comme une base de données
util_CONSTRAINTS : liste des contraintes sur les tables
« interne » est géré dynamiquement par le noyau d’Oracle. Les
(owner, constraint-name, constraint-type, table_name,
objets qu’il contient appartiennentà l’utilisateur SYS. search_condition, r-owner, r-constraint_name)
Il peut être consulté par les utilisateurs au travers de vues util_INDEXES : liste des index sur les tables et clusters
particulières, la vue dictionnary fournissant elle, la liste (owner, index_name, table_owner, table_name, table_type,
complète des objets constituant le dictionnaire : uniqueness, tablespace_name, ini_trans…)
select * from dictionnary ;
util_OBJECTS : liste des objets
(owner, object_name, object_id, object_type, created,
Structure du dictionnaire modified)
util_SYNONYMS : liste des synonymes
Il est formé de quatre classes de vues. Les trois premières (owner, synonym_name, table_owner, table_name, db_link)
rassemblent des vues de noms identiques, au préfixe près, ce dernier util_TABLES : liste des tables
indiquant la nature des objets concernés par la vue. Ce peut être : (owner, table_name, tablespace_name, cluster_name, …)
util_TAB_PRIVS : liste des privilèges
USER_ : la vue porte sur les objets propriétés de l’utilisateur (grantee, owner, table_name, grantor, select_priv, insert_priv,
ALL_ : la vue porte sur les objets accessibles à l’utilisateur delete_priv,update_priv, references_priv, alter_priv,
DBA_ : la vue porte sur tous les objets (nécessite le privilège DBA). index_ priv, created)

43
Jean Armand YOMBI en homage à Julien SCHNNEL

util_TABLESPACES : description des tablespaces SESSION_PRIVS : privilèges accordés à l’utilisateur


(tablespace_name, initial_extent, next_extent, min_extents, (privilege)
max_extents, pct_increase, status)
SESSION_ROLES : rôles validés pour l’utilisateur
util_TRIGGERS : liste des triggers possédés (role)
(owner, trigger_name, trigger_type,triggering_event,
table_owner, table_name,referencing_names, when_clause,
status, description, trigger_body)

util_TS_QUOTAS : quotas sur les tablespaces


(tablespace_name, bytes, max_bytes, blocks, max_blocks)

util _ VIEWS : liste des vues


(owner, view_name, text_length, text)

ALL_USERS : caractéristiques de tous les utilisateurs


(username, user_id, created)

USER_USERS : mes caractérisques


(username, user_id, connect_priv, resource_priv, dba_priv,
default_tablespace, temporary_tablespace, created, expires)

DICTIONARY : liste de toutes les tables et vues


(table_name, comments)

DICT_COLUMNS : description des colonnes des objets du


dictionnaire
( table_name, column_name, comments)

EXCEPTIONS : informations sur la violation de contraintes


d’intégrité
(row_id owner table_name constraint)

44
Jean Armand YOMBI en homage à Julien SCHNNEL

Exercice Annexe (variante des exemples grant/revoke, pour les amateurs


de gauloises)
Nous supposons qu’il existe dans la table emp une colonne
ident_oracle, donnant pour chaque employé son compte Oracle Hypothèse : abraracourcix, propriétaire de emp et dept, est aux
pour se connecter à la base. commandes
Que se passe t-il lorsqu’un utilisateur consulte l’objet devinette
défini ci-après ? grant select on dept
to assurancetourix, idefix ;
Commandes écrites par l’utilisateur chirac :
grant select, insert, update on emp
create view my_departement as to public ;
select * from emp
where deptno = (select deptno from emp grant all on dept to obelix;
where job= Manager grant all on emp to obelix;
and upper(ident_oracle)= upper(user) );

grant select on my_department to public ;


revoke select on dept from assurancetourix;

create public synonym devinette for my_department ; revoke insert, update on emp from public ;

voir exemple : les utilisateurs n’ont plus, sur emp, que le droit
select, obelix conserve les droits qu’il a obtenu personnellement
en

revoke delete on dept from obelix ;

Combinaison de et : obelix a tous les droits sur dept, sauf


delete.

revoke all on dept from obelix ;


revoke all on emp from obelix;

Plus aucun droit pour obelix.

45
Jean Armand YOMBI en homage à Julien SCHNNEL

grant select, update Annexe (algèbre relationnelle)


on dept to asterix with grant option ;
asterix bénéficie à présent des privilèges select, update sur emp et select e.name, e.sal r1 = restrict (emp, sal>3000)
de la possibilité de transmettre ceux-ci à d’autres utilisateurs. from emp e resultat = proj (emp, {ename, job})
where e.sal > 3000 ;
astérix ne se fait pas prier et propage…
select distinct ename, job resultat = proj (emp, {ename, , job} )
grant select, update on abraracourcix.dept to from emp ;
diagnostic ;
grant select on abraracourcix.dept to doubleclix select dname r1 = rstrict (dept, loc= Chicago ou
with grant option; loc=’Dallas’)
from dept resultat = proj (r1, { dname})
(l’utilisation d’un synonme pour abraracourcix.dept faciliterait la where loc in
lourde tâche d’astérix) (‘CHICAGO’,‘DALLAS’);

grant select, update (sal, comm) selec e. * r1 = restrict (dept, loc= CHICAGO)
on emp to bonemine ; from emp e r2 = proj ( r1, {deptno} )
where e.deptno in resultat = join (emp, r2, emp.deptno=
create role chefs identified by gaule; r2.deptno)
(select d.deptno
from dept d
grant all on emp to chefs; where d.loc =‘CHICAGO’);
grant insert on dept to chefs;
grant select, update on dept to chefs with grant select dname from dept r1 = restrict (emp, empno=66)
option ; where deptno in r2 = proj (r1, {job} )
(select deptno from emp r3 = join (emp, r2, emp.job=r2.job)
Donner des droits à un rôle where job = r4 = proj (r3, {deptno} )
( select job from emp r5 = join (r4, dept, r4.deptno=
grant chefs to obelix ; dept.deptno)
revoke chefs from obelix; where empno=66 ) ) ; resultat = proj (r5, {dname})

grant chefs to astérix; select e. * , dname r1 = restrict (dept, loc= Chicago)


from emp e, dept de r2 = proj (r1 , {deptno, dname} )
Donner un rôle à un utilisateur ; l’utilisateur hérite automatiquement where e.deptno= d.deptno resultat=join (emp, r2, emp.deptno=r2.
deptno)
des droits attachés au rôle chefs. and loc = ‘CHICAGO’ ;

46
Jean Armand YOMBI en homage à Julien SCHNNEL

select deptno from dept r1 = proj (emp, {deptno})


where deptno not in r2 = proj (dept, {deptno})
(select deptno from emp) resultat = r2 \r1

47

Vous aimerez peut-être aussi