SQL
SQL
SQL
Langage SQL
version 5.7 du polycopié
Richard Grin
4 janvier 2008
Table des matières
Présentation du polycopié vi
1 Introduction 1
1.1 Présentation de SQL . . . . . . . . . . . . . . . . . . . . . . . 1
1.5.1 Identicateurs . . . . . . . . . . . . . . . . . . . . . . . 3
1.5.2 Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.5.3 Colonnes . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.8 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
ii
TABLE DES MATIÈRES iii
4 Interrogations 26
4.1 Syntaxe générale . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2 Clause SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2.1 select comme expression . . . . . . . . . . . . . . . . . 27
4.2.2 Pseudo-colonnes . . . . . . . . . . . . . . . . . . . . . . 28
4.3 Clause FROM . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.4 Clause WHERE . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.4.1 Clause WHERE simple . . . . . . . . . . . . . . . . . . 31
4.4.2 Opérateurs logiques . . . . . . . . . . . . . . . . . . . . 33
4.5 Jointure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.5.1 Jointure naturelle . . . . . . . . . . . . . . . . . . . . . 35
4.5.2 Jointure d'une table avec elle-même . . . . . . . . . . . 35
4.5.3 Jointure externe . . . . . . . . . . . . . . . . . . . . . . 36
4.5.4 Jointure non équi . . . . . . . . . . . . . . . . . . . . 37
4.6 Sous-interrogation . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.6.1 Sous-interrogation à une ligne et une colonne . . . . . . 38
4.6.2 Sous-interrogation ramenant plusieurs lignes . . . . . . 39
4.6.3 Sous-interrogation synchronisée . . . . . . . . . . . . . 40
4.6.4 Sous-interrogation ramenant plusieurs colonnes . . . . 41
4.6.5 Clause EXISTS . . . . . . . . . . . . . . . . . . . . . . 41
4.7 Fonctions de groupes . . . . . . . . . . . . . . . . . . . . . . . 45
4.8 Clause GROUP BY . . . . . . . . . . . . . . . . . . . . . . . . 45
4.9 Clause HAVING . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.10 Fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.10.1 Fonctions arithmétiques . . . . . . . . . . . . . . . . . 48
4.10.2 Fonctions chaînes de caractères . . . . . . . . . . . . . 48
4.10.3 Fonctions de travail avec les dates . . . . . . . . . . . . 51
4.10.4 Fonction de choix (CASE) . . . . . . . . . . . . . . . . 51
4.10.5 Nom de l'utilisateur . . . . . . . . . . . . . . . . . . . . 53
4.11 Clause ORDER BY . . . . . . . . . . . . . . . . . . . . . . . . 53
4.12 Opérateurs ensemblistes . . . . . . . . . . . . . . . . . . . . . 54
4.12.1 Opérateur UNION . . . . . . . . . . . . . . . . . . . . 55
iv TABLE DES MATIÈRES
5.9.1 GRANT . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5.9.2 REVOKE . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.9.3 Changement de mot de passe . . . . . . . . . . . . . . 83
5.9.4 Synonyme . . . . . . . . . . . . . . . . . . . . . . . . . 84
5.9.5 Création d'un utilisateur, rôle . . . . . . . . . . . . . . 84
vi
Chapitre 1
Introduction
1
2 CHAPITRE 1. INTRODUCTION
SQL utilise des identicateurs pour désigner les objets qu'il manipule :
utilisateurs, tables, colonnes, index, fonctions, etc.
Un identicateur est un mot formé d'au plus 30 caractères, commençant
obligatoirement par une lettre de l'alphabet. Les caractères suivants peuvent
être une lettre, un chire, ou l'un des symboles # $ et _. SQL ne fait pas la
diérence entre les lettres minuscules et majuscules. Les voyelles accentuées
ne sont pas acceptées.
Un identicateur ne doit pas gurer dans la liste des mot clés réservés (voir
manuel de référence Oracle). Voici quelques mots clés que l'on risque d'utiliser
comme identicateurs : ASSERT, ASSIGN, AUDIT, COMMENT, DATE,
DECIMAL, DEFINITION, FILE, FORMAT, INDEX, LIST, MODE, OP-
TION, PARTITION, PRIVILEGES, PUBLIC, REF, REFERENCES, SE-
LECT, SEQUENCE, SESSION, SET, TABLE, TYPE.
1.5.2 Tables
Remarques 1.1
(a) Selon la norme SQL-2, le nom d'une table devrait être précédé d'un
nom de schéma (voir 5.1).
4 CHAPITRE 1. INTRODUCTION
(b) Il est d'usage (mais non obligatoire évidemment) de mettre les noms
de table au singulier : plutôt EMPLOYE que EMPLOYES pour une
table d'employés.
Exemple 1.1
Table DEPT des départements :
Table DUAL
Exemple 1.2
Acher la date d'aujourd'hui, le nom de l'utilisateur et le résultat d'un
calcul :
1.5.3 Colonnes
Les données contenues dans une colonne doivent être toutes d'un même
type de données. Ce type est indiqué au moment de la création de la table
qui contient la colonne (voir 2.1).
Chaque colonne est repérée par un identicateur unique à l'intérieur de
chaque table. Deux colonnes de deux tables diérentes peuvent porter le
même nom. Il est ainsi fréquent de donner le même nom à deux colonnes
de deux tables diérentes lorsqu'elles correspondent à une clé étrangère à la
clé primaire référencée. Par exemple, la colonne Dept des tables DEPT et
EMP.
Une colonne peut porter le même nom que sa table.
Le nom complet d'une colonne est en fait celui de sa table, suivi d'un
point et du nom de la colonne. Par exemple, la colonne DEPT.LIEU
Le nom de la table peut être omis quand il n'y a pas d'ambiguïté sur la
table à laquelle elle appartient, ce qui est généralement le cas.
1.6. TYPES DE DONNÉES 5
Exemple 1.3
SALAIRE DECIMAL(8,2)
dénit une colonne numérique SALAIRE. Les valeurs auront au maxi-
mum 2 décimales et 8 chires au plus au total (donc 6 chires avant le
point décimal).
Les constantes numériques ont le format habituel : -10, 2.5, 1.2E-8 (ce
−8
dernier représentant 1.2 x 10 ).
Oracle n'a qu'un seul type numérique NUMBER. Par soucis de compati-
bilité, Oracle permet d'utiliser les types SQL-2 mais ils sont ramenés au type
NUMBER.
Lors de la dénition d'une colonne de type numérique, on peut préciser le
nombre maximum de chires et de décimales qu'une valeur de cette colonne
pourra contenir :
NUMBER
NUMBER(taille_maxi )
NUMBER(taille_maxi, décimales )
6 CHAPITRE 1. INTRODUCTION
Si le paramètre décimales n'est pas spécié, 0 est pris par défaut. La valeur
128
absolue du nombre doit être inférieure à 10 . NUMBER est un nombre à
virgule ottante (on ne précise pas le nombre de chires après la virgule) qui
peut avoir jusqu'à 38 chires signicatifs.
L'insertion d'un nombre avec plus de chires que taille_maxi sera refusée
(taille_maxi ne prend en compte ni le signe ni le point décimal). Les déci-
males seront éventuellement arrondies en fonction des valeurs données pour
taille_maxi et décimales.
Les types Oracle sont les types SQL-2 mais le type VARCHAR s'appelle
VARCHAR2 dans Oracle (la taille maximum est de 2000 caractères).
1.6. TYPES DE DONNÉES 7
TIME pour les heures, minutes et secondes (les secondes peuvent comporter
un certain nombre de décimales) ;
Oracle ore le type DATE comme en SQL-2 mais pour Oracle une donnée
de type DATE inclut un temps en heures, minutes et secondes.
Une constante de type date est une chaîne de caractères entre apos-
trophes. Le format dépend des options que l'administrateur a choisies au
moment de la création de la base. S'il a choisi de franciser la base, le for-
mat d'une date est jour/mois/année, par exemple, '25/11/1992' (le format
américain par défaut donnerait '25-NOV-1992'). L'utilisateur peut saisir
des dates telles que '3/8/1993' mais les dates sont toujours achées avec
deux chires pour le jour et le mois, par exemple, '03/08/1993'.
Remarque 1.2
Ne pas oublier de donner 4 chires pour l'année, sinon la date risque
d'être mal interprétée par Oracle (voir remarque 4.12 page 51).
Ce type permet d'enregistrer des données telles que les images et les sons,
de très grande taille et avec divers formats.
SQL-2 fournit les types BIT et BIT VARYING (longueur constante ou
non).
Les diérents SGBD fournissent un type pour ces données mais les noms
varient : LONG RAW pour Oracle, mais IMAGE pour Sybase, BYTE pour Informix,
etc.
Nous n'utiliserons pas ce type de données dans ce cours.
8 CHAPITRE 1. INTRODUCTION
Une colonne qui n'est pas renseignée, et donc vide, est dite contenir la
valeur NULL. Cette valeur n'est pas zéro, c'est une absence de valeur. Voir
aussi 1.8.2.
Exemples 1.4
(a) SELECT * FROM DEPT
(b) SELECT NOME, POSTE FROM EMP
(c) SELECT NOME , SAL + NVL(COMM,0) FROM EMP
Exemple 1.5
SELECT MATR, NOME, SAL * 1.15
FROM EMP
WHERE SAL + NVL(COMM,0) >= 12500
1.8. EXPRESSIONS 9
1.8 Expressions
1.8.1 Contenu d'une expression, opérateurs et fonctions
Les expressions acceptées par SQL portent sur des colonnes, des constantes,
des fonctions.
Ces trois types d'éléments peuvent être reliés par des opérateurs arith-
métiques (+ - * /), maniant des chaînes de caractères (|| pour concaténer
des chaînes), des dates (- donne le nombre de jours entre deux dates).
Les priorités des opérateurs arithmétiques sont celles de l'arithmétique
classique (* et /, puis + et -). Il est possible d'ajouter des parenthèses dans
les expressions pour obtenir l'ordre de calcul que l'on désire.
Les expressions peuvent gurer :
en tant que colonne résultat d'un SELECT
dans une clause WHERE
dans une clause ORDER BY (étudiée en 4.11)
dans les ordres de manipulations de données (INSERT, UPDATE, DE-
LETE étudiés au chapitre 3)
Le tableau qui suit donne le nom des principales fonctions (voir 4.10 pour
plus de détails).
DE GROUPE ARITHMETIQUES
DE CHAINES DE DATES
SUM NVL NVL NVL
COUNT TO_CHAR SUBSTR TO_CHAR
VARIANCE SQRT LENGTH ADD_MONTHS
MAX ABS INSTR MONTHS_BETWEEN
MIN POWER TO_NUMBER NEXT_DAY
Exemple 1.6
select coalesce(salaire, commission, 0) from emp
Cette requête renvoie le salaire s'il n'est pas null. S'il est null, renvoie
la commission si elle n'est pas null. Sinon elle renvoie 0.
10 CHAPITRE 1. INTRODUCTION
Exemple 1.8
select NULLIF(salaire, -1) from emp
Chapitre 2
Création d'une table et
contraintes d'intégrité
Exemple 2.1
CREATE TABLE article (
ref VARCHAR(10) constraint pk_article primary key,
nom VARCHAR(30) NOT NULL,
prix DECIMAL(9,2),
datemaj DATE)
11
12 CHAPITRE 2. CRÉATION D'UNE TABLE ET CONTRAINTES
On peut donner une valeur par défaut pour une colonne si la colonne n'est
pas renseignée.
Exemple 2.2
CREATE TABLE article (
ref VARCHAR(10) constraint pk_article primary key,
nom VARCHAR(30) NOT NULL,
prix DECIMAL(9,2),
datemaj DATE DEFAULT CURRENT_DATE)
sur une colonne : la contrainte porte sur une seule colonne. Elle suit la
dénition de la colonne dans un ordre CREATE TABLE (pas possible
dans un ordre ALTER TABLE).
sur une table : la contrainte porte sur une ou plusieurs colonnes. Elles se
place au même niveau que les dénition des colonnes dans un ordre
CREATE TABLE ou ALTER TABLE.
Contrainte d'unicité
Remarque 2.1
Cette contrainte UNIQUE convient à des clés candidates. Cependant
une colonne UNIQUE peut avoir des valeurs NULL et une contrainte
UNIQUE ne correspond donc pas toujours à un identicateur.
La norme SQL2 ore 4 autres options qui ne sont pas implémentée dans
Oracle :
ON DELETE SET DEFAULT met une valeur par défaut dans la clé
étrangère quand la clé primaire référencée est supprimée.
ON UPDATE SET NULL met NULL dans la clé étrangère quand la clé
primaire référencée est modiée.
ON UPDATE SET DEFAULT met une valeur par défaut dans la clé
étrangère quand la clé primaire référencée est modiée.
Contrainte CHECK
CHECK(condition )
donne une condition que les colonnes de chaque ligne devront vérier (exemples
dans la section suivante). On peut ainsi indiquer des contraintes d'intégrité de
domaines. Cette contrainte peut être une contrainte de colonne ou de table.
Si c'est une contrainte de colonne, elle ne doit porter que sur la colonne en
question.
Exemples de contraintes
Exemples 2.3
(a) Quelques contraintes sur des colonnes :
Exemple 2.4
ALTER TABLE EMP
DROP CONSTRAINT NOM_UNIQUE
ADD CONSTRAINT SAL_MIN CHECK(SAL + NVL(COMM,0) > 1000)
RENAME CONSTRAINT NOM1 TO NOM2
MODIFY CONSTRAINT SAL_MIN DISABLE
Les contraintes d'intégrité sont parfois gênantes. On peut vouloir les en-
lever pour améliorer les performances durant le chargement d'une grande
quantité de données dans la base. Pour cela, Oracle fournit la commande
ALTER TABLE ... DISABLE/ENABLE. Il faut l'utiliser avec précaution
lorsque l'on est certain qu'aucune donnée ajoutée pendant l'invalidation de
la contrainte ne violera la contrainte.
Exemple 2.5
ALTER TABLE EMP
DISABLE CONSTRAINT NOM_UNIQUE
La clause ENABLE a une option qui permet de conserver dans une table
les lignes qui ne respectent pas la contrainte réactivée.
16 CHAPITRE 2. CRÉATION D'UNE TABLE ET CONTRAINTES
Exemple 2.6
create table emp (
matr integer constraint emp_pk primary key,
. . .,
sup integer CONSTRAINT EMP_REF_SUP REFERENCES EMP DEFERRABLE,
. . .);
. . .
Voici une procédure SQL*PLUS Oracle pour faire acher les contraintes
en utilisant des tables du dictionnaire des données. Si vous voulez faire acher
en plus si la contrainte est diérable, il sut d'ajouter la colonne DEFERRABLE
de la vue USER_CONSTRAINTS.
COLUMN TABLE FORMAT A9
COLUMN COLONNE FORMAT A9
COLUMN CONTRAINTE FORMAT A12
COLUMN "TABLE REF" FORMAT A9
COLUMN "COL REF" FORMAT A9
COLUMN "TEXTE CONTRAINTE" FORMAT A20
3.1 Insertion
INSERT INTO table (col1,..., coln )
VALUES (val1,...,valn )
ou
INSERT INTO table (col1,..., coln )
SELECT ...
table est le nom de la table sur laquelle porte l'insertion. col1,..., coln est la
liste des noms des colonnes pour lesquelles on donne une valeur. Cette liste
est optionnelle. Si elle est omise, ORACLE prendra par défaut l'ensemble des
colonnes de la table dans l'ordre où elles ont été données lors de la création
de la table. Si une liste de colonnes est spéciée, les colonnes ne gurant pas
dans la liste auront la valeur NULL.
19
20 CHAPITRE 3. LANGAGE DE MANIPULATION DES DONNÉES
Exemples 3.1
(a) INSERT INTO dept
VALUES (10, 'FINANCES', 'PARIS')
(b) INSERT INTO dept (lieu, nomd, dept)
VALUES ('GRENOBLE', 'RECHERCHE', 20)
La deuxième forme avec la clause SELECT permet d'insérer dans une table
des lignes provenant d'une table de la base. Le SELECT a la même syntaxe
qu'un SELECT normal.
Exemple 3.2
Enregistrer la participation de MARTIN au groupe de projet numéro
10 :
Exemple :
3.2 Modication
La commande UPDATE permet de modier les valeurs d'un ou plusieurs
champs, dans une ou plusieurs lignes existantes d'une table.
UPDATE table
SET col1 = exp1, col2 = exp2, ...
WHERE prédicat
ou
UPDATE table
SET (col1, col2,...) = (SELECT ...)
WHERE prédicat
3.3. SUPPRESSION 21
table est le nom de la table mise à jour ; col1, col2, ... sont les noms des co-
lonnes qui seront modiées ; exp1, exp2,... sont des expressions. Elles peuvent
aussi être un ordre SELECT renvoyant les valeurs attribuées aux colonnes
(deuxième variante de la syntaxe).
Les valeurs de col1, col2... sont mises à jour dans toutes les lignes satisfai-
sant le prédicat. La clause WHERE est facultative. Si elle est absente, toutes
les lignes sont mises à jour.
Le prédicat peut contenir des sous-interrogations (voir 4.6).
Exemples 3.3
(a) Faire passer MARTIN dans le département 10 :
UPDATE EMP
SET DEPT = 10
WHERE NOME = 'MARTIN'
(b) Augmenter de 10 % les commerciaux :
UPDATE EMP
SET SAL = SAL * 1.1
WHERE POSTE = 'COMMERCIAL'
(c) Donner à CLEMENT un salaire 10 % au dessus de la moyenne des
salaires des secrétaires :
UPDATE EMP
SET SAL = (SELECT AVG(SAL) * 1.10
FROM EMP
WHERE POSTE = 'SECRETAIRE')
WHERE NOME = 'CLEMENT'
On remarquera que la moyenne des salaires sera calculée pour les va-
leurs qu'avaient les salaires au début de l'exécution de la commande
UPDATE et que les modications eectuées sur la base pendant l'exé-
cution de cette commande ne seront pas prises en compte.
UPDATE EMP
SET COMM = NULL
WHERE NOME = 'MARTIN'
3.3 Suppression
L'ordre DELETE permet de supprimer des lignes d'une table.
22 CHAPITRE 3. LANGAGE DE MANIPULATION DES DONNÉES
3.4 Transactions
3.4.1 Généralités sur les transactions
Dénitions
Exemple 3.5
Une transaction peut transférer une somme d'argent entre deux comptes
d'un client d'une banque. Elle comporte deux ordres : un débit sur un
compte et un crédit sur un autre compte. Si un problème empêche le
crédit, le débit doit être annulé.
les modications déjà eectuées par cette instruction sont annulées. Mais
cette erreur ne provoque pas nécessairement de rollback automatique de la
transaction.
Remarque 3.2
Certains ordres SQL, notamment ceux de dénitions de données (create
table...), provoquent une validation automatique de la transaction en
cours.
Dans la norme SQL, la structure des transactions est plate et les transac-
tions sont chaînées :
2 transactions ne peuvent se chevaucher ;
une transaction commence dès que la précédente se termine.
Ce modèle n'est pas toujours adapté aux situations concrètes, surtout
pour les transactions longues et multi-sites :
elles peuvent être une source de frustration pour l'utilisateur si tout le
travail eectué depuis le début de la transaction est annulée ;
le fait que les transactions gardent jusqu'à leur n les verrous qu'elles
ont posés nuit à la concurrence.
D'autres modèles ont été proposés pour assouplir ce modèle.
Transactions emboîtées
Points de reprise
26
4.2. CLAUSE SELECT 27
d'éliminer les duplications : si, dans le résultat, plusieurs lignes sont iden-
tiques, une seule sera conservée.
Exemples 4.1
(a) SELECT * FROM DEPT
(b) SELECT DISTINCT POSTE FROM EMP
(c) SELECT NOME, SAL + NVL(COMM,0) AS Salaire FROM EMP
(d) La requête suivante va provoquer une erreur car on utilise le nom Salaire
dans la clause where :
Exemple 4.2
SELECT NOME, SAL + NVL(COMM,0) "Salaire Total" FROM EMP
Le nom complet d'une colonne d'une table est le nom de la table suivi d'un
point et du nom de la colonne. Par exemple : EMP.MATR, EMP.DEPT,
DEPT.DEPT
Le nom de la table peut être omis quand il n'y a pas d'ambiguïté. Il
doit être précisé s'il y a une ambiguïté, ce qui peut arriver quand on fait une
sélection sur plusieurs tables à la fois et que celles-ci contiennent des colonnes
qui ont le même nom (voir en particulier 4.5).
La norme SQL-2, mais pas tous les SGBD, permet d'avoir des select em-
boîtés parmi les expressions. Il faut éviter cette facilité dans les programmes
si on veut qu'ils soient portables. Rien n'empêche de l'utiliser en interactif si
elle existe.
C'est possible avec Oracle :
select nomE, sal/(select sum(sal) from emp)*100
from emp
Un select expression doit ramener une valeur au plus. S'il ne ramène
aucune valeur, l'expression est égale à la valeur null.
Si cette possibilité existe, le select emboîté peut même alors être synchro-
nisé avec le select principal (le vérier sur le SGBD que vous utilisez). La
requête suivante ache les noms des employés avec le nombre d'employés qui
gagnent plus :
28 CHAPITRE 4. INTERROGATIONS
select nomE,
(select count(*) from emp where sal > e1.sal) as rang
from emp e1
Attention, avec Oracle on ne peut utiliser rang dans la clause where (à
vérier sur votre SGBD). Par exemple, la requête suivante renverra une er-
reur :
select nomE,
(select count(*) from emp where sal > e1.sal) as rang
from emp e1
where rang < 8
Si on veut contourner cette erreur, on peut le faire ainsi (mais il y a un
moyen plus simple pour obtenir les 8 plus gros salaires) :
select nome, rang + 1
from (select nome,
(select count(*) from emp
where sal > e1.sal) as rang
from emp e1)
where rang < 5
order by rang;
4.2.2 Pseudo-colonnes
rownum est le numéro des lignes sélectionnées par une clause where : le
rownum de la première ligne a la valeur 1, celui de la deuxième la
valeur 2, etc.
select nome
from (select rownum RANG, nome from emp where sal > 2000)
where RANG > 5
On peut ainsi récupérer les lignes numérotées entre deux nombres :
certaines ambiguïtés, quand la même table est utilisée de plusieurs façons dif-
férentes dans une même interrogation (voir 4.5.2 ou 4.6.3 pour des exemples
caractéristiques). Quand on a donné un synonyme à une table dans une re-
quête, elle n'est plus reconnue sous son nom d'origine dans cette requête.
Le nom complet d'une table est celui de son créateur (celui du nom du
schéma selon la norme SQL-2 : voir 5.1), suivi d'un point et du nom de la
table. Par défaut, le nom du créateur est celui de l'utilisateur en cours. Ainsi,
on peut se dispenser de préciser ce nom quand on travaille sur ses propres
tables. Mais il faut le préciser dès que l'on se sert de la table d'un autre
utilisateur.
Quand on précise plusieurs tables dans la clause FROM, on obtient le
produit cartésien des tables. On verra plus loin (remarque 4.5 page 34) une
syntaxe spéciale pour les produits cartésiens.
Exemple 4.3
Produit cartésien des noms des départements par les numéros des dé-
partements :
DEPT NOMD
---- ------------------
10 FINANCES
20 FINANCES
30 FINANCES
10 RECHERCHE
20 RECHERCHE
30 RECHERCHE
10 VENTES
20 VENTES
30 VENTES
La norme SQL2 (et les dernières versions d'Oracle) permet d'avoir un
SELECT à la place d'un nom de table.
Exemples 4.4
(a) Pour obtenir la liste des employés avec le pourcentage de leur salaire
par rapport au total des salaires, il fallait auparavant utiliser une vue
(voir 5.3). Il est maintenant possible d'avoir cette liste avec une seule
instruction SELECT :
Remarque 4.1
Ce select n'est pas une sous-interrogation ; on ne peut synchroniser le
select avec les autres tables du from (voir 4.6.3).
La clause where est étudiée ici pour la commande SELECT. Elle peut se
rencontrer aussi dans les commandes UPDATE et DELETE avec la même
syntaxe.
WHERE prédicat
Un prédicat simple est la comparaison de deux expressions ou plus au
moyen d'un opérateur logique :
32 CHAPITRE 4. INTERROGATIONS
Remarques 4.2
(a) L'utilisation des jokers ne fonctionne qu'avec LIKE ; elle ne fonctionne
pas avec =.
Exemples 4.5
(a) Sélectionner les employés du département 30 ayant un salaire supérieur
à 1500 frs.
4.5 Jointure
Quand on précise plusieurs tables dans la clause FROM, on obtient le pro-
duit cartésien des tables. Ce produit cartésien ore en général peu d'intérêt.
34 CHAPITRE 4. INTERROGATIONS
Exemple 4.6
Liste des employés avec le nom du département où ils travaillent :
Remarque 4.4
Cette syntaxe SQL2 n'est pas supportée par tous les SGBD (par exemple,
les versions d'Oracle antérieures à la version 9 ne la supportaient pas).
La jointure peut aussi être traduite par la clause WHERE :
Cette façon de faire est encore très souvent utilisée, même avec les
SGBD qui supportent la syntaxe SQL2.
Remarque 4.5
La norme SQL2 a aussi une syntaxe spéciale pour le produit cartésien
de deux tables :
Remarque 4.6
Si on utilise une jointure naturelle, il est interdit de préxer une co-
lonne utilisée pour la jointure par un nom de table. La requête suivante
provoque une erreur :
Il peut être utile de rassembler des informations venant d'une ligne d'une
table avec des informations venant d'une autre ligne de la même table.
Dans ce cas il faut renommer au moins l'une des deux tables en lui don-
nant un synonyme (voir 4.3), an de pouvoir préxer sans ambiguïté chaque
nom de colonne.
36 CHAPITRE 4. INTERROGATIONS
Exemple 4.7
Lister les employés qui ont un supérieur, en indiquant pour chacun le
nom de son supérieur :
Remarque 4.7
Oracle n'accepte cette syntaxe que depuis la version 9. Pour les versions
plus anciennes, la requête doit s'écrire :
On peut aussi dire ça autrement : la table qui n'a pas le (+) correspond
à la table qui aura chacune de ses lignes achée, même si l'autre table
n'a pas de ligne correspondante. On l'appellera la table dominante.
Cette interprétation convient mieux pour retenir la syntaxe SQL2.
On ne peut ajouter de (+) des deux côtés ; on doit utiliser une union
(voir 4.12.1) si on veut faire acher les lignes qui n'ont pas de lignes
correspondantes pour les deux tables.
Exemples 4.8
(a) Liste des employés, avec tous les employés qui gagnent plus :
4.6 Sous-interrogation
Une caractéristique puissante de SQL est la possibilité qu'un prédicat
employé dans une clause WHERE (expression à droite d'un opérateur de
comparaison) comporte un SELECT emboîté.
Par exemple, la sélection des employés ayant même poste que MARTIN
peut s'écrire en joignant la table EMP avec elle-même :
SELECT EMP.NOME
FROM EMP JOIN EMP MARTIN ON EMP.POSTE = MARTIN.POSTE
WHERE MARTIN.NOME = 'MARTIN'
mais on peut aussi la formuler au moyen d'une sous-interrogation :
SELECT NOME FROM EMP
WHERE POSTE = (SELECT POSTE
FROM EMP
WHERE NOME = 'MARTIN')
Exemple 4.9
Liste des employés travaillant dans le même département que MER-
CIER :
Exemples 4.10
(a) Liste des employés du département 10 ayant même poste que quelqu'un
du département VENTES :
FROM EMP
WHERE DEPT = (SELECT DEPT
FROM DEPT
WHERE NOMD = 'VENTES'))
(b) Liste des employés ayant même poste que MERCIER ou un salaire
supérieur à CHATEL :
Exemple 4.11
Liste des employés travaillant à LYON et ayant même poste que FRE-
MONT.
Exemple 4.12
Liste des employés gagnant plus que tous les employés du départe-
ment 30 :
Exemple 4.13
Liste des employés ne travaillant pas dans le même département que
leur supérieur.
Exemple 4.14
Employés ayant même poste et même salaire que MERCIER :
Exemple 4.15
SELECT NOMD FROM DEPT
WHERE EXISTS (SELECT NULL FROM EMP
WHERE DEPT = DEPT.DEPT AND SAL > 10000);
Cette interrogation liste le nom des départements qui ont au moins
un employé ayant plus de 10.000 comme salaire ; pour chaque ligne de
DEPT la sous-interrogation synchronisée est exécutée et si au moins
42 CHAPITRE 4. INTERROGATIONS
une ligne est trouvée dans la table EMP, EXISTS prend la valeur vrai
et la ligne de DEPT satisfait les critères de l'interrogation.
Remarque 4.9
Il faut se méer lorsque l'on utilise EXISTS en présence de valeurs
NULL. Si on veut par exemple les employés qui ont la plus grande
commission par la requête suivante,
Exemple 4.16
La réponse à la question Quels sont les départements qui participent à
tous les projets ? est fourni par R ÷Dept S où R = (PARTICIPATION
JN {Matr} EMP) [Dept, CodeP] ( JN {Matr} indique une jointure na-
turelle sur l'attribut Matr) et S = PROJET [CodeP]
SELECT DEPT
FROM PARTICIPATION NATURAL JOIN EMP E1
WHERE NOT EXISTS
(SELECT CODEP FROM PROJET
WHERE NOT EXISTS
(SELECT DEPT, CODEP
FROM PARTICIPATION NATURAL JOIN EMP
WHERE DEPT = E1.DEPT
AND CODEP = PROJET.CODEP))
Remarque 4.10
Il faudrait ajouter DISTINCT dans le premier select pour éviter
les doublons.
Sur ce cas particulier on voit qu'il est inutile de travailler sur la join-
ture de PARTICIPATION et de EMP pour le SELECT externe. On
peut travailler sur la table DEPT. Il en est de même sur tous les cas
où la table R est une jointure. D'après cette remarque, le SELECT
précédent devient :
ne contient dans la colonne qui sert pour la division que des valeurs qui
existent dans la table diviseur, on peut exprimer la division en utilisant
les regroupements (étudiés dans la prochaine section) et en comptant
les lignes regroupées. Pour l'exemple des départements qui participent
à tous les projets, on obtient :
select dept
from emp natural join participation
group by dept
having count(distinct codeP) =
(select count(distinct codeP) from projet)
Mais il ne faut pas oublier que dans des requêtes complexes les don-
nées qui interviennent dans les divisions peuvent provenir de requêtes
emboîtées. Il n'y a alors pas nécessairement de contraintes de référence
comme dans l'exemple traité ici (contrainte qui impose que codeP doit
nécessairement correspondre à un codeP dans la table Projet). Si on
n'a pas A ⊆ B, le fait que A et B aient le même nombre d'éléments ne
signie pas que A = B.
S'il peut y avoir dans la colonne qui sert pour la division des valeurs
qui n'existent pas dans la table diviseur, la requête est légèrement plus
complexe :
select dept
from emp natural join participation
where codeP in
(select codeP from projet)
group by dept
having count(distinct codeP) =
(select count(distinct codeP) from projet)
4.7. FONCTIONS DE GROUPES 45
Exemples 4.17
(a) SELECT COUNT(*) FROM EMP
(b) SELECT SUM(COMM) FROM EMP WHERE DEPT = 10
Les valeurs NULL sont ignorées par les fonctions de groupe. Ainsi, SUM(col)
est la somme des valeurs qui ne sont pas égales à NULL de la colonne 'col'.
De même, AVG est la somme des valeurs non NULL divisée par le nombre
de valeurs non NULL.
Il faut remarquer qu'à un niveau de profondeur (relativement aux sous-
interrogations), d'un SELECT, les fonctions de groupe et les colonnes doivent
être toutes du même niveau de regroupement. Par exemple, si on veut le nom
et le salaire des employés qui gagnent le plus dans l'entreprise, la requête
suivante provoquera une erreur :
SELECT NOME, SAL FROM EMP
WHERE SAL = MAX(SAL)
Il faut une sous-interrogation car MAX(SAL) n'est pas au même niveau de
regroupement que le simple SAL :
SELECT NOME, SAL FROM EMP
WHERE SAL = (SELECT MAX(SAL) FROM EMP)
même valeur. Cette clause se place juste après la clause WHERE, ou après
la clause FROM si la clause WHERE n'existe pas.
Des lignes peuvent être éliminées avant que le groupe ne soit formé grâce
à la clause WHERE.
Exemples 4.18
(a) SELECT DEPT, COUNT(*) FROM EMP
GROUP BY DEPT
(b) SELECT DEPT, COUNT(*) FROM EMP
WHERE POSTE = 'SECRETAIRE'
GROUP BY DEPT
(c) SELECT DEPT, POSTE, COUNT(*) FROM EMP
GROUP BY DEPT, POSTE
(d) SELECT NOME, DEPT FROM EMP
WHERE (DEPT, SAL) IN
(SELECT DEPT, MAX(SAL) FROM EMP
GROUP BY DEPT)
RESTRICTION :
Exemple 4.19
SELECT DEPT, COUNT(*)
FROM EMP
WHERE POSTE = 'SECRETAIRE'
GROUP BY DEPT HAVING COUNT(*) > 1
4.10 Fonctions
Nous allons décrire ci-dessous les principales fonctions disponibles dans
Oracle. Il faut remarquer que ces fonctions ne sont pas standardisées et ne
sont pas toutes disponibles dans les autres SGBD ; elles peuvent aussi avoir
une syntaxe diérente,ou même un autre nom.
48 CHAPITRE 4. INTERROGATIONS
Exemple 4.20
Calcul du salaire journalier :
Exemple 4.21
Position du deuxième 'A' dans les postes :
Le paramètre car est optionnel. Par défaut, chaîne est complétée par des
espaces.
RTRIM(chaîne, car )
a une fonction analogue, les caractères étant supprimés à l'extrémité droite
de la chaîne. Si l'ensemble des caractères n'est pas donné, ce sont les espaces
qui sont enlevés.
Exemple : remplacer les A et les M par des * dans les noms des employés :
Exemple 4.22
Achage des salaires avec au moins trois chires (dont deux déci-
males) :
Exemple 4.23
SELECT TO_CHAR(DATEMB, 'DD/MM/YY HH24')
WHERE TO_CHAR(DATEMB) LIKE '%/05/91'
TO_NUMBER (chaîne )
convertit une chaîne de caractères en nombre (quand la chaîne de caractères
est composée de caractères numériques.
ASCII(chaîne )
donne le code ASCII du premier caractère de chaîne.
CHR(n ) donne le caractère de code ASCII n.
4.10. FONCTIONS 51
TO_DATE(chaîne, format )
permet de convertir une chaîne de caractères en donnée de type date. Le
format est identique à celui de la fonction TO_CHAR.
Remarque 4.12
Attention à l'interprétation par Oracle des dates ne contenant que 2
chires pour l'année. Toute année inférieure à 50 est considérée comme
une année du 21ème siècle ; les autres années sont considérées comme
étant des années du 20ème siècle. Par exemple, 38 correspond à 2038
et 50 correspond à 1950.
Par défaut Oracle ache les années avec 2 chires. Pour savoir à coup
TO_CHAR :
sûr de quelle année il s'agit, il faut utiliser la fonction
ROUND(date, précision )
arrondit la date à la précision spéciée. La précision est indiquée en utilisant
un des masques de mise en forme de la date.
SYSDATE ou CURRENT_DATE
a pour valeur la date et l'heure courante du système d'exploitation hôte.
Une fonction de choix existe dans la norme SQL2 (et dans Oracle depuis
la version 9i). Elle correspond à la structure switch du langage C (ou case
de Pascal ou Ada).
Il existe deux syntaxes pour CASE : une qui donne une valeur suivant des
conditions quelconques et une qui donne une valeur suivant la valeur d'une
expression.
52 CHAPITRE 4. INTERROGATIONS
CASE
WHEN condition1 THEN expression1
[WHEN condition2 THEN expression2 ]
. . .
[ELSE expression_défaut ]
END
Remarques 4.13
(a) La condition qui suit un WHEN peut être n'importe quelle expression
booléenne.
(b) Si aucune condition n'est remplie et s'il n'y a pas de ELSE, null est
retourné.
CASE expression
WHEN valeur1 THEN expression1
[WHEN valeur2 THEN expression2 ]
. . .
[ELSE expression_défaut]
END
Remarques 4.14
(a) Attention, ne fonctionne pas pour le cas où une des valeurs n'est pas
renseignée (when null then). Pour ce cas, il faut utiliser l'autre syn-
taxe de case : when colonne is null then.
(b) Si l'expression n'est égale à aucune valeur et s'il n'y a pas de ELSE,
null est retourné.
Exemple 4.24
Liste des employés avec leur catégorie (président = 1, directeur = 2,
autre = 3), en appelant la colonne Niveau :
SELECT nome,
CASE
WHEN (poste = 'Président') THEN 1
WHEN (poste = 'Directeur') THEN 2
ELSE 3
END Niveau
FROM emp;
pourrait aussi s'écrire plus simplement
4.11. CLAUSE ORDER BY 53
SELECT nome,
CASE poste
WHEN 'Président' THEN 1
WHEN 'Directeur' THEN 2
ELSE 3
END Niveau
FROM emp;
Pour les versions d'Oracle antérieures à la version 9i, il est possible d'uti-
liser la fonction decode.
DECODE(crit, val1, res1 [,val2, res2,...], defaut )
permet de choisir une valeur parmi une liste d'expressions, en fonction de la
valeur prise par une expression servant de critère de sélection : elle prend la
valeur res1 si l'expression crit a la valeur val1, prend la valeur res2 si crit
a la valeur val2,... ; si l'expression crit n'est égale à aucune des expressions
val1, val2... , DECODE prend la valeur defaut par défaut.
Les expressions résultat (res1, res2, defaut ) peuvent être de types dié-
rents : caractère et numérique, ou caractère et date (le résultat est du type
de la première expression rencontrée dans le DECODE).
Les expression val et res peuvent être soit des constantes, soit des
colonnes ou même des expressions résultats de fonctions.
Exemple 4.25
Liste des employés avec leur catégorie (président = 1, directeur = 2,
autre = 3) :
USER
a pour valeur le nom sous lequel l'utilisateur est entré dans Oracle.
SELECT SAL FROM EMP WHERE NOME = USER
L'option facultative DESC donne un tri par ordre décroissant. Par dé-
faut, l'ordre est croissant.
Le tri se fait d'abord selon la première expression, puis les lignes ayant la
même valeur pour la première expression sont triées selon la deuxième, etc.
Les valeurs nulles sont toujours en tête quel que soit l'ordre du tri (ascendant
ou descendant).
Pour préciser lors d'un tri sur quelle expression va porter le tri, il est
possible de donner le rang relatif de la colonne dans la liste des colonnes,
plutôt que son nom. Il est aussi possible de donner un nom d'en-tête de
colonne du SELECT (voir 4.2).
Exemple 4.26
À la place de : SELECT DEPT, NOMD FROM DEPT ORDER BY NOMD
on peut taper : SELECT DEPT, NOMD FROM DEPT ORDER BY 2
Cette nouvelle syntaxe doit être utilisée pour les interrogations exprimées
à l'aide d'un opérateur booléen UNION, INTERSECT ou MINUS.
Elle permet aussi de simplier l'écriture d'un tri sur une colonne qui
contient une expression complexe.
Exemples 4.27
(a) Liste des employés et de leur poste, triée par département et dans
chaque département par ordre de salaire décroissant :
Exemple 4.28
Liste des ingénieurs des deux liales :
Exemple 4.29
Liste des départements qui ont des employés dans les deux liales :
Exemple 4.30
Liste des départements qui ont des employés dans la première liale
mais pas dans la deuxième.
Exemple 4.31
Un programme demande son nom et son mot de passe à un utilisateur,
et les range dans 2 variables nom et mdp.
4.14. INJECTION DE CODE SQL 57
5.1 Schéma
Un schéma est un ensemble d'objets (tables, vues, index, autorisations,
etc...) gérés ensemble. On pourra ainsi avoir un schéma lié à la gestion du
personnel et un autre lié à la gestion des clients. Un schéma est créé par la
commande CREATE SCHEMA AUTHORIZATION.
Cette notion introduite par la norme SQL2 n'est pas vraiment prise en
compte par Oracle qui identie pour le moment un nom de schéma avec un
nom d'utilisateur.
Autre notion de SQL2, le catalogue, est un ensemble de schémas. Un cata-
logue doit nécessairement comprendre un schéma particulier qui correspond
au dictionnaire des données (voir 5.8).
5.2 Tables
5.2.1 CREATE TABLE AS
59
60 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
Exemple 5.1
CREATE TABLE MINIDEPT(CLE INTEGER, NOM VARCHAR(20)) AS SELECT
DEPT, NOMD FROM DEPT
Cet ordre créera une table MINIDEPT et la remplira avec deux co-
lonnes des lignes de la table DEPT.
Les sections 2.2.2 et 2.2.3 montrent comment gérer les contraintes d'inté-
grité avec la commande ALTER TABLE. Cette commande permet aussi de
gérer les colonnes d'une table : ajout d'une colonne (après toutes les autres
colonnes), suppression et modication d'une colonne existante.
Exemple 5.2
alter table personne
add (email_valide char(1)
constraint personne_email_valide check(email_valide in ('o', 'n')))
bien sûr déjà exister dans la table. type1, type2,... sont les nouveaux types
que l'on désire attribuer aux colonnes.
Il est possible de modier la dénition d'une colonne, à condition que la
colonne ne contienne que des valeurs NULL ou que la nouvelle dénition soit
compatible avec le contenu de la colonne :
on ne peut pas diminuer la taille maximale d'une colonne.
on ne peut spécier 'NOT NULL' que si la colonne ne contient pas de
valeur nulle.
Il est toujours possible d'augmenter la taille maximale d'une colonne, tant
qu'on ne dépasse pas les limites propres à SQL, et on peut dans tous les cas
spécier 'NULL' pour autoriser les valeurs nulles.
Exemple 5.3
alter table personne
modify (
prenoms null,
nom varchar(50))
On peut donner une contrainte de colonne dans la nouvelle dénition de
la colonne.
Exemple 5.4
alter table personne modify (
sexe char(1)
constraint personne_sexe_ck check(sexe in ('m', 'f')))
Oracle n'a ajouté cette possibilité que depuis la version 8i. Auparavant, il
fallait se contenter de mettre toutes les valeurs de la colonne à NULL (si on
voulait récupérer de la place). On pouvait aussi se débarrasser de la colonne
en créant une nouvelle table sans la colonne en copiant les données par create
table as, et en renommant la table du nom de l'ancienne table.
ALTER TABLE table
DROP COLUMN col
La colonne supprimée ne doit pas être référencée par une clé étrangère ou
être utilisée par un index.
Si une table ou une vue (étudié en 5.3) doit être utilisée par plusieurs utili-
sateurs, il peut être intéressant de lui donner un synonyme public pour que les
utilisateurs ne soient pas obligés de préxer le nom de la table ou de la vue par
le nom de son créateur. Oracle ore la commande create public synonym
pour cela.
Exemple 5.5
CREATE PUBLIC SYNONYM employe FOR toto.emp
5.3 Vues
Une vue est une vision partielle ou particulière des données d'une ou
plusieurs tables de la base.
La dénition d'une vue est donnée par un SELECT qui indique les don-
nées de la base qui seront vues.
5.3. VUES 63
Exemples 5.6
(a) Vue ne comportant que le matricule, le nom et le département des
employés :
Exemple 5.7
Vue constituant une restriction de la table EMP aux employés du dé-
partement 10 :
Une vue peut être référencée dans un SELECT de la même façon qu'une
table. Ainsi, il est possible de consulter la vue EMP10. Tout se passe comme
s'il existait une table EMP10 des employés du département 10 :
SELECT * FROM EMP10
Exemple 5.8
CREATE VIEW EMP10 AS
SELECT * FROM EMP
WHERE DEPT = 10
WITH CHECK OPTION
Remarque 5.2
Les restrictions données ci-dessus sont les restrictions de la norme
SQL2. Elles sont parfois trop strictes et les SGBD peuvent assouplir ces
5.3. VUES 65
UPDATE EMP
SET nomE = 'Dupont'
where nomE = 'Dupond'
De façon générale, les vues permettent de dissocier la façon dont les utili-
sateurs voient les données, du découpage en tables. On sépare l'aspect externe
(ce que voit un utilisateur particulier de la base) de l'aspect conceptuel (com-
ment a été conçu l'ensemble de la base). Ceci favorise l'indépendance entre
les programmes et les données. Si la structure des données est modiée, les
programmes ne seront pas à modier si l'on a pris la précaution d'utiliser
des vues (ou si on peut se ramener à travailler sur des vues). Par exemple, si
une table est découpée en plusieurs tables après l'introduction de nouvelles
données, on peut introduire une vue, jointure des nouvelles tables, et la nom-
mer du nom de l'ancienne table pour éviter de réécrire les programmes qui
utilisaient l'ancienne table. En fait, si les données ne sont pas modiables à
travers la vue (voir 5.3.3, il faudra utiliser des trigger instead of (voir ??)
pour utiliser pleinement la vue comme une table ; sinon la vue ne pourra être
utilisée que pour récupérer des données mais pas pour les modier.
Une vue peut aussi être utilisée pour restreindre les droits d'accès à cer-
taines colonnes et à certaines lignes d'une table : un utilisateur peut ne pas
avoir accès à une table mais avoir les autorisations pour utiliser une vue qui
ne contient que certaines colonnes de la table ; on peut de plus ajouter des
restrictions d'utilisation sur cette vue comme on le verra en 5.9.1.
Dans le même ordre d'idées, une vue peut être utilisée pour implanter
une contrainte d'intégrité grâce à l'option WITH CHECK OPTION.
Une vue peut également simplier la consultation de la base en enregis-
trant des SELECT complexes.
Exemple 5.9
En créant la vue
66 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
5.4 Index
Considérons le SELECT suivant :
SELECT * FROM EMP WHERE NOME = 'MARTIN'
Un moyen de retrouver la ou les lignes pour lesquelles NOME est égal à
'MARTIN' est de balayer toute la table.
Un tel moyen d'accès conduit à des temps de réponse prohibitifs pour des
tables dépassant quelques milliers de lignes.
Une solution est la création d'index, qui permettra de satisfaire aux re-
quêtes les plus fréquentes avec des temps de réponses acceptables.
Un index est formé de clés auxquelles SQL peut accéder très rapidement.
Comme pour l'index d'un livre, ces clés permettent de lire ensuite directement
les données repérées par les clés.
Remarque 5.3
Deux index construits sur des tables d'un même utilisateur ne peuvent
avoir le même nom (même s'ils sont liés à deux tables diérentes).
Un index peut être créé juste après la création d'une table ou sur une
table contenant déjà des lignes. Il sera ensuite tenu à jour automatiquement
lors des modications de la table.
Un index peut porter sur plusieurs colonnes : la clé d'accès sera la conca-
ténation des diérentes colonnes.
On peut créer plusieurs index indépendants sur une même table.
5.4. INDEX 67
Les requêtes SQL sont transparentes au fait qu'il existe un index ou non.
C'est l'optimiseur de requêtes du SGBD qui, au moment de l'exécution de
chaque requête, recherche s'il peut s'aider d'un index.
La principale utilité des index est d'accélérer les recherches d'informations
dans la base. Une ligne est retrouvée instantanément si la recherche peut
utiliser un index. Sinon, une recherche séquentielle sur toutes les lignes de la
table doit être eectuée. Il faut cependant noter que les données à retrouver
doivent correspondre à environ moins de 20 % de toutes les lignes sinon une
recherche séquentielle est préférable.
Les index concaténés (avec plusieurs colonnes) permettent même dans
certains cas de récupérer toutes les données cherchées sans accéder à la table.
Une jointure s'eectuera souvent plus rapidement si une des colonnes de
jointure est indexée (s'il n'y a pas trop de valeurs égales dans les colonnes
indexées).
Les index accélèrent le tri des données si le début de la clé de tri corres-
pond à un index.
Une autre utilité des index est d'assurer l'unicité d'une clé en utilisant
l'option UNIQUE. Ainsi la création de l'index suivant empêchera l'insertion
dans la table EMP d'un nom d'employé existant :
CREATE UNIQUE INDEX NOME ON EMP (NOME)
Il faut cependant savoir que les modications des données sont ralenties
si un ou plusieurs index doivent être mis à jour. De plus, la recherche d'in-
formation n'est accélérée par un index que si l'index ne contient pas trop de
données égales. Il n'est pas bon, par exemple, d'indexer une colonne SEXE
qui ne pourrait contenir que des valeurs M ou F.
Un autre problème est que la modication des données provoque la po-
sition de verrou sur une partie de l'index pour éviter les problèmes liés aux
accès multiples aux données. Les accès aux données en peuvent donc être
ralentis.
On peut dire qu'il n'est pas toujours facile de savoir si un index doit être
créé ou non. Si la table est rarement modiée un index occupe seulement
de la place et c'est l'optimiseur de requêtes qui choisira s'il l'utilise ou non.
Les inconvénients sont donc minimes en ce cas. Il n'en est pas de même si
la table est souvent modiée. Il ne faudra alors créer un index que si on
pense qu'il améliorera vraiment les performances pour les requêtes les plus
courantes ou les plus critiques. On a vu ci-dessus des règles générales pouvant
aider à faire un choix, par exemple, un index ne donnera pas d'amélioration
pour une requête si plus de 20 % des lignes sont récupérées. Ces règles ne
sont pas à prendre au pied de la lettre et il faut souvent les adapter aux
68 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
situations particulières. Il faut aussi consulter les notes de version des SGBD
qui donnent d'autres règles qui dépendent des versions des optimiseurs de
requêtes. Il peut aussi se poser le choix du type d'index (voir 5.4.4).
Remarque 5.4
Un index est automatiquement supprimé dès qu'on supprime la table
à laquelle il appartient.
l'on cherche. On rappelle que les accès disques sont environ un million de fois
plus lents que les accès en mémoire centrale.
Un autre avantage est que l'on peut très facilement lire les clés dans
l'ordre. L'application d'une clause order by peut ainsi bénécier de ces
index.
Il existe aussi d'autres types d'index qui peuvent être utilisés dans des
circonstances particulières ; les plus courants sont les suivants :
Index bitmap : ils ne sont utiles que lorsque les données de la table ne
sont presque jamais modiées. Ils sont le plus souvent utilisés dans les
applications décisionnelles OLAP (On Line Analytical Processing) qui
facilitent les prises de décisions liées à l'analyse des données conser-
vées par une entreprise. L'implémentation est très diérente de celle
des B-arbres. Pour chaque valeur distincte de la colonne indexée l'in-
dex contient un tableau de bits (autant de bits que de lignes dans la
table) indiquant si chaque ligne de la table a cette valeur. Il est facile
de combiner diérents tableaux de bits pour répondre aux sélections
de type col1=valeur1 and col2=valeur2 où col1 et col2 sont in-
dexées par un index bitmap. Lorsque les index bitmap sont utilisés par
l'optimiseur ils peuvent fournir de très bonnes performances. Oracle
a aussi introduit un nouveau type d'index bitmap pour accélérer les
jointures.
Index de type table de hachage : ils ne sont plus vraiment utilisés car ils
n'orent pas d'avantages conséquents par rapport aux B-arbres. Ils
orent un accès quasi instantané à une ligne dont on donne la clé
mais ils ne permettent pas le parcours dans l'ordre des clés et ne sont
donc d'aucune utilité pour les sélections du type col1 > valeur1.
On trouve ce type d'index dans PostgreSQL mais pas dans Oracle.
Index sur des valeurs de fonction : ils peuvent être utilisés pour accélérer
les recherches du type col1 > fonction(...). Ce sont les résultats
des valeurs d'une fonction sur toutes les lignes de la table qui sont
indexés.
L'utilisateur peut avoir des informations sur les index qu'il a créés en
consultant la table USER_INDEX du dictionnaire des données. La table ALL_INDEX
lui donne les index qu'il peut utiliser (même s'il ne les a pas créées).
70 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
Dans les premiers temps des SGBD, les développeurs utilisaient des va-
leurs enregistrées dans des tables de la base pour créer les identicateurs
dont ils avaient besoin. L'idée est de créer une suite de nombres entiers de
telle sorte que jamais le même nombre n'est utilisé deux fois, même si deux
transactions distinctes ont besoin d'un identicateur en même temps. Voici
les procédés les plus courants :
Le premier identicateur des lignes d'une table est égal à 1. Pour trou-
ver les identicateurs suivants il sut d'ajouter 1 à la plus grande valeur
de la table ; par exemple,
select max(matr) + 1 from employe
Cette requête a déjà un coût non négligeable. Mais pour éviter les pro-
blèmes bien connus des accès concurrents (cf. 6) il est en plus nécessaire
de bloquer toute la table pendant la récupération du maximum.
Cette technique est beaucoup trop coûteuse dans les environnements à
forte concurrence. De plus, si on veut garder un historique des données
enregistrées dans la base, on peut se retrouver avec des lignes qui ont eu
le même identicateur (il sut que la ligne de plus grand identicateur
soit supprimée à un moment donné).
Pour éviter de bloquer la table des employés, une autre technique est de
créer une table qui ne contient qu'une seule ligne d'une seule colonne.
Cette colonne contient la valeur du prochain identicateur à utiliser.
Pour les mêmes raisons que pour la solution précédente on est obligé de
bloquer la table pendant l'attribution d'un identicateur. Mais l'avan-
tage est que l'on ne bloque pas toute la table des employés, que l'on n'a
pas à eectuer une recherche de maximum, que cette table est petite
et qu'elle sera donc le plus souvent entièrement en mémoire cache du
SGBD. Une telle table peut fournir les identicateurs à toutes les tables
(ou à plusieurs tables) ou elle peut ne fournir les identicateurs qu'à
une seule table. Dans le premier cas, les attentes (dues au blocage de
5.5. GÉNÉRATION DE CLÉS PRIMAIRES 71
Tous les SGBD orent désormais une facilité pour obtenir des identi-
cateurs sans avoir à accéder à une table. Cette facilité permet d'obtenir des
valeurs qui sont générées automatiquement par le SGBD. Cette facilité n'est
malheureusement pas standardisée ; par exemple,
MySQL permet d'ajouter la clause AUTO_INCREMENT à une colonne ;
DB2 et SQL Server ont une clause IDENTITY pour dire qu'une colonne
est un identiant ;
Oracle, DB2 et PostgreSQL utilisent des séquences.
La section suivante présente les séquences.
5.5.3 Séquences
Exemple 5.10
create sequence seqdept
increment by 10
start with 10
Remarque 5.5
Utiliser un incrément supérieur à 1 permet de disposer de plusieurs
identicateurs en un seul appel, pour améliorer les performances.
72 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
Exemple 5.11
insert into dept(dept, nomd, lieu)
values (seqdept.nextval, 'Finances', 'Nice')
currval avec la
Pour voir la valeur d'une séquence, on utilise table dual
(voir 1.5.2) : select seqdept.currval from dual.
Remarques 5.6
(a) currval n'est pas déni tant qu'on n'a pas appelé au moins une fois
nextval dans la session de travail.
(b) La valeur de currval ne dépend que des nextval lancés dans la même
transaction.
(c) nextval modie immédiatement les valeurs futures renvoyées par les
nextval des autres sessions, même s'il est lancé dans une transaction
non validée.
Exemple 5.12
alter sequence seqdept increment by 5
On ne peut pas modier le numéro de démarrage de la séquence.
L'utilisateur peut avoir des informations sur les séquences qu'il a créées
en consultant la table USER_SEQUENCES du dictionnaire des données. La table
ALL_SEQUENCES lui donne les séquences qu'il peut utiliser (même s'il ne les a
pas créées).
5.6. PROCÉDURE ET FONCTION STOCKÉE 73
Exemple 5.13
Voici une procédure stockée Oracle qui prend en paramètre un nu-
méro de département et un pourcentage, augmente tous les salaires
74 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
update emp
set sal = sal * (1 + pourcentage / 100)
where dept = unDept;
end;
Remarques 5.7
(a) Sous Oracle, on peut avoir une description des paramètres d'une pro-
cédure stockée par la commande DESC nom-procédure .
(b) Les erreurs de compilation des procédures stockées peuvent être vues
sous Oracle par la commande SQL*PLUS show errors. On peut
aussi voir ces erreurs en utilisant le dictionnaire des données (voir 5.6.3).
Exemple 5.14
Le code suivant crée une fonction qui permet le calcul en franc d'un
montant en euros :
Ces fonctions peuvent alors être utilisées comme les fonctions prédé-
nies dans les requêtes SQL.
Pour avoir les noms des procédures on peut utiliser les vues USER_PROCEDURES
ou ALL_OBJECTS. La vue USER_SOURCE donne les sources des procédures
(chaque ligne de la table contient une ligne de code).
Exemples 5.15
(a) Voici un ordre SQL pour avoir, sous Oracle, les noms des procédures
stockées et le nom de leur propriétaire :
5.7 Triggers
Les triggers (déclencheurs en français) ressemblent aux procédures sto-
ckées car ils sont eux aussi compilés et enregistrés dans le dictionnaire des
données de la base et ils sont le plus souvent écrits dans le même langage.
La diérence est que leur exécution est déclenchée automatiquement par
des événements liés à des actions sur la base. Les événements déclencheurs
peuvent être les commandes LMD insert, update, delete ou les commandes
LDD create, alter, drop.
76 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
Ils peuvent aussi être utilisés pour d'autres usages comme de mettre à
jour des données de la base suite à une modication d'une donnée.
Si l'exécution d'un trigger provoque une erreur, par exemple s'il viole une
contrainte d'intégrité, la requête qui l'a déclenché est annulée (mais pas la
transaction en cours). Les actions eectuées par un trigger font partie de
la même transaction que l'action qui les a déclenchés. Un rollback va donc
annuler aussi tout ce qu'ils ont exécuté.
La syntaxe :
CREATE [OR REPLACE] TRIGGER nom-trigger
{BEFORE | AFTER } {INSERT | DELETE | UPDATE [OF col1, col2,... ]}
ON {nom-table | nom-vue }
[REFERENCING ...]
[FOR EACH ROW]
[WHEN condition ]
bloc PL/SQL
Pour supprimer un trigger :
Remarque 5.8
Toutes les possibilités oertes par les triggers ne sont pas décrites ici
et chaque SGBD peut ajouter des fonctionnalités. Pour plus d'informa-
tions consultez la documentation de votre SGBD.
Remarque 5.9
L'outil SQL*FORMS d'Oracle (construction et utilisation d'écrans de
saisie) utilise aussi le terme de trigger mais pour des programmes dont
l'exécution est déclenchée par des actions de l'utilisateur, qui ne sont
pas toujours liées aux données enregistrées dans la base (par exemple,
sortie d'une zone de saisie ou entrée dans un bloc logique de l'écran de
saisie).
5.7. TRIGGERS 77
5.7.2 Exemple
Une table cumul sert à enregistrer le cumul des augmentations dont ont
bénécié les employés d'une entreprise.
Exemple 5.16
Le trigger suivant met à jour automatiquement une table cumul qui
totalise les augmentations de salaire de chaque employé.
commit ou de rollback.
Le code d'un trigger ne peut contenir de
Un trigger ne peut modier par une commande update, insert ou delete
la table indiquée dans la dénition du trigger (celle sur laquelle a eu lieu
l'action qui a déclenché l'exécution du trigger). Mais un trigger for each
row peut modier les lignes concernées par la requête SQL qui a déclenché
le trigger, en utilisant l'ancienne et la nouvelle valeur.
Exemple 5.17
create or replace trigger incremente_version
after update on emp
for each row
begin
-- version est une colonne de la table emp
:new.version := :old.version + 1;
end;
Il est possible d'ajouter une clause WHEN pour restreindre les cas où le
trigger est exécuté. WHEN est suivi de la condition nécessaire à l'exécution du
trigger.
Cette condition peut référencer la nouvelle et l'ancienne valeur d'une
colonne de la table (new et old ne doivent pas être préxés par : comme
à l'intérieur du code du trigger.
5.7. TRIGGERS 79
Exemple 5.18
create or replace trigger modif_salaire_trigger
before update of sal on emp
for each row
when (new.sal < old.sal)
begin
raise_application_error(-20001,
'Interdit de baisser le salaire ! ('
|| :old.nome || ')');
end;
raise_application_error est une instruction Oracle qui permet de
déclencher une erreur en lui associant un message et un numéro (com-
pris entre -20000 et -20999).
Ces triggers servent à utiliser les vues non modiables pleinement comme
des tables.
Ils existent dans la plupart des SGBD (Oracle, DB2, SQL Server par
exemple), mais pas dans tous (pas dans MySQL en particulier).
Dans Oracle, un tel trigger ne peut porter que sur une vue (pas sur une
table).
Syntaxe :
CREATE [OR REPLACE] TRIGGER nom-trigger
INSTEAD OF {INSERT | DELETE | UPDATE} ON nom-vue
[REFERENCING ...]
[FOR EACH ROW]
bloc PL/SQL
Exemple 5.19
Soit une vue qui joint les tables EMP et DEPT :
values(:new.dept, :new.nom_dept);
insert into emp(matr, nome, dept)
values(:new.matr, :new.nom_emp, :new.dept);
end;
Il est alors possible d'insérer un nouvel employé et un nouveau dépar-
tement avec la commande
BASE_OBJECT_TYPE TABLE_NAME
---------------- ----------
TABLE EMP
COLUMN_NAME REFERENCING_NAMES
----------- --------------------------------
REFERENCING NEW AS NEW OLD AS OLD
ACTION_TYPE TRIGGER_BODY
----------- ----------------------------------------------
PL/SQL BEGIN insert into cumul (matricule, augmentation)
values (:NEW.matr, 0); END;
5.8. DICTIONNAIRE DE DONNÉES 81
Des vues de ces tables permettent à chaque utilisateur de ne voir que les
objets qui lui appartiennent ou sur lesquels il a des droits. D'autres vues sont
réservées aux administrateurs de la base.
Exemples 5.20
(a) Colonnes de la table EMP :
SELECT * FROM COLS WHERE TNANE = 'EMP'
82 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
5.9.1 GRANT
Exemple 5.21
L'utilisateur DUBOIS peut autoriser l'utilisateur CLEMENT à lire sa
table EMP :
5.9.2 REVOKE
Remarque 5.10
Si on enlève un privilège à un utilisateur, ce privilège est automatique-
ment retiré à tout autre utilisateur à qui il aurait accordé ce privilège.
Tout utilisateur peut modier son mot de passe par l'ordre GRANT
CONNECT :
GRANT CONNECT TO utilisateur IDENTIFIED BY mot-de-passe
84 CHAPITRE 5. LANGAGE DE DÉFINITION DES DONNÉES
5.9.4 Synonyme
Oracle (et d'autres SGBD comme SQL Server) permet de donner des
synonymes pour les tables et vues.
Les synonymes permettent le plus souvent des noms simpliés. Les sy-
nonymes peuvent être publics s'ils sont connus de tous les utilisateurs de la
base, ou privés s'ils ne sont connus que de celui qui a créé le synonyme.
CREATE [ PUBLIC | PRIVATE ] SYNONYM nom_synonyme FOR objet
Les synonymes publics sont particulièrement intéressants quand ils per-
mettent de ne pas préxer une table ou une vue par le nom du propriétaire
lorsque l'utilisateur du synonyme n'est pas le propriétaire de la table ou de
la vue.
Exemple 5.22
CREATE PUBLIC SYNONYM departement FOR toto.dept
86
6.1. PROBLÈMES LIÉS AUX ACCÈS CONCURRENTS 87
Pour éviter ce genre de situation, les SGBD bloquent l'accès aux tables
(ou parties de tables : blocs mémoire ou lignes par exemple) lorsque de nou-
veaux accès pourraient occasionner des problèmes. Les processus qui veulent
accéder aux tables bloquées sont mis en attente jusqu'à ce que les tables
soient débloquées.
Une transaction T2 lit une valeur V donnée par une autre transaction T1.
Ensuite la transaction T1 annule son aectation de V et la valeur lue par T2
est donc fausse.
Une transaction lit deux fois une même valeur et ne trouve pas la même
valeur les deux fois.
88 CHAPITRE 6. GESTION DES ACCÈS CONCURRENTS
Pour éviter ceci, T1 devra bloquer les données qu'elle veut modier entre
les temps t1 et t3, pour empêcher les autres transactions de les modier (voir,
par exemple, les blocages explicites d'Oracle en 6.5).
Une variante que l'on peut rencontrer si on veut accéder aux données
depuis un langage de programmation tel que Java : on commence par lire le
nombre de lignes qui vérient un critère pour dimensionner un tableau Java
qui les contiendra ; on relance ensuite la même sélection pour ranger les lignes
dans le tableau ; si entre temps un autre utilisateur a rajouté des lignes qui
vérient ce critère, on provoque une erreur (le tableau n'est plus assez grand
pour contenir toutes les lignes).
Un blocage de ligne n'est plus la solution ici car ces lignes n'existent pas
à la première lecture. On sera souvent amené à eectuer un blocage explicite
de table, ou à choisir le degré d'isolation serializable (décrit dans la section
suivante).
Pour éviter tous les problèmes décrits dans la section précédente, la ges-
tion des transactions doit, si possible, rendre les transactions sérialisable :
6.2. ISOLATION DES TRANSACTIONS 89
1. acquisition de tous les verrous pour les objets sur lesquels on va agir ;
Si l'on est pessimiste, on pense qu'il y aura forcément des problèmes d'ac-
cès concurrent. Pour pouvoir faire tranquillement son travail, on (les transac-
tions qu'on lance) bloque donc les données sur lesquelles on veut travailler.
Un tel blocage durera le temps de la transaction en cours.
6.3. TRAITEMENT POUR LES ACCÈS CONCURRENTS 91
Ce mode pessimiste est à éviter si possible dans les traitements longs, par
exemple ceux qui comportent une intervention de l'utilisateur ou des accès
distants avec risque d'attente au cours de la transaction.
Si l'on est optimiste, on pense que tout va bien se passer et que les autres
transactions ne vont pas modier les données sur lesquelles on va travailler.
On n'eectue donc aucun blocage.
Remarque 6.1
Le traitement optimiste permet une granularité très ne (au niveau des
attributs et pas des lignes) dans le cas où la validation de la transaction
utilise la comparaison des valeurs des données utilisées. En eet, rien
n'empêche une autre transaction de modier des données des lignes que
l'on utilise à partir du moment où elle ne modie pas les attributs qui
sont intervenus dans le traitement.
des données pendant l'exécution d'un seul ordre SQL ; par exemple, un ordre
SELECT ou UPDATE va travailler sur les lignes telles qu'elles étaient au
moment du début de l'exécution de la commande, même si entre-temps une
autre transaction validée par un COMMIT a modié certaines de ces lignes.
De même, si une commande UPDATE comporte un SELECT emboîté, les
modications de la commande UPDATE ne sont pas prises en compte par
le SELECT emboîté. Les SGBDs comme DB2 qui ne conservent pas plu-
sieurs versions des données récemment modiées n'orent pas cette lecture
consistante.
Aucun SGBD n'assure automatiquement une lecture consistante pendant
toute une transaction. Si une transaction est validée, toutes les autres tran-
sactions voient ensuite les modications qu'elle a eectuée. Ce comportement
n'est pas souhaité pour des traitements, tels que les bilans, qui souhaitent
voir toutes les données comme elles étaient au moment du début de la tran-
saction. Il est cependant possible d'obtenir une lecture consistante pendant
toute une transaction. On peut
soit indiquer que la transaction est en lecture seule par
set transaction read only (voir 6.5.1), mais, dans ce cas, la tran-
saction ne pourra pas modier des données ;
soit passer au niveau d'isolation serializable (voir 6.2.2), ce qui est pé-
nalisant au niveau des performances ;
soit eectuer des blocages explicites (voir 6.5).
Les écritures bloquent les autres écritures : si une transaction tente de
modier une ligne déjà modiée par une autre transaction non validée, elle
est mise en attente. Les mises à jour perdues sont ainsi évitées.
Certains SGBDs bloquent les lignes lues. Dans son mode de fonctionne-
ment par défaut DB2 bloque chaque ligne lue du résultat d'un select, jusqu'à
la lecture de la prochaine ligne (ou la n de la transaction). Oracle ne bloque
jamais les lignes lues.
Une particularité d'Oracle est que les lectures ne bloquent jamais les
modications et qu'une modication ne bloque jamais les lectures :
Une lecture n'eectue aucune blocage. La lecture d'une donnée ne pose
aucun verrou sur la donnée lue et une autre transaction peut donc mo-
dier la donnée. Pour une transaction en mode read committed, cela
revient à avoir un comportement optimiste (voir 6.3.2). Si ce compor-
tement optimiste n'est pas souhaité, il est possible d'utiliser select for
update (voir 6.5.1) pour bloquer explicitement les données lues.
Si une donnée a été modiée par une transaction en cours non encore
validée, les autres transactions peuvent tout de même lire cette donnée
mais puisque la transaction n'est pas encore validée, les autres tran-
sactions lisent la valeur que la donnée avait avant la modication de la
94 CHAPITRE 6. GESTION DES ACCÈS CONCURRENTS
transaction.
Ces comportements sont mis en ÷uvre par les SGBDs en provoquant im-
plicitement des blocages sur les lignes ou les tables impliquées lors de certains
traitements : DELETE, UPDATE, INSERT, SELECT FOR UPDATE et les
ordres de dénitions et de contrôle des données : LDD (Langage de Dénition
des Données) et LCD (Langage de Contrôle des Données) : ALTER TABLE,
GRANT, etc. Certains SGBDs (mais pas Oracle) posent aussi un verrou avec
la commande SELECT.
Voici les blocages eectués implicitement par Oracle :
Ordre SQL Blocage niveau ligne Blocage niveau table
DELETE, UPDATE Exclusif Row Exclusive
INSERT Row Exclusive
SELECT FOR UPDATE Exclusif Row Share
LDD/LCD Exclusif
Tous les SGBDs n'orent pas exactement les mêmes types de blocages.
Nous allons étudier dans ce cours les blocages oerts par Oracle. La plupart
des notions décrites dans cette section se retrouvent dans les autres SGBD,
6.5. BLOCAGES EXPLICITES 95
Les commandes qui provoquent des blocages explicites sont lock table
et select for update.
Voici les cinq variantes de la commande LOCK TABLE, de la plus
restrictive à la moins restrictive :
IN EXCLUSIVE MODE
IN SHARE ROW EXCLUSIVE MODE
IN SHARE MODE
IN ROW EXCLUSIVE
IN ROW SHARE MODE
Il s'agit d'un blocage de table, sauf si le mot ROW apparaît. Tous les
blocages de lignes impliquent un autre blocage de table (vous comprendrez
cette phrase en lisant les détails de chaque commande ci-dessous).
Au niveau des lignes il n'existe que le blocage exclusif : même si plusieurs
transactions peuvent bloquer en même temps des lignes, elles ne peuvent
bloquer les mêmes lignes.
Les blocages explicites peuvent conduire à des interblocages. Oracle dé-
tecte et résout les interblocages (en annulant certaines des requêtes bloquées).
Un verrouillage dure le temps d'une transaction. Il prend n au premier
COMMIT ou ROLLBACK (explicite ou implicite).
Ce mode étant très contraignant pour les autres utilisateurs (ils sont mis
en attente et ne reprennent la main qu'au déblocage de la table), le blocage
doit être le plus court possible. Un blocage en mode exclusif doit être suivi
rapidement d'un COMMIT ou d'un ROLLBACK.
Remarque 6.2
Pour les 5 modes de blocage, l'option NOWAIT (ajoutée à la n de
la commande LOCK) permet de reprendre immédiatement la main au
cas où la table que l'on veut bloquer serait déjà bloquée. Par exemple :
1. on indique les lignes que l'on veut se réserver. Pour cela on utilise la
variante de la commande SELECT avec la clause FOR UPDATE OF.
Remarque 6.3
Si on n'eectue pas ce type de blocage sur les données que l'on veut
modier, on risque d'avoir un problème de mise à jour perdue : les
données que l'on a lues par un SELECT pour les modier ont été mo-
diées par une autre transaction avant qu'on ait le temps d'enregistrer
leur nouvelle valeur. On peut choisir de ne pas eectuer ce blocage et
faire un traitement optimiste (on espère qu'aucune transaction n'a
travaillé sur les mêmes données) et des vérications au moment du
COMMIT pour voir si on avait eectivement raison d'être optimiste
(voir 6.3.2 page 91).
Tableau récapitulatif
Ce tableau indique les commandes qui sont autorisées dans chacun des
modes de blocage.
6.5. BLOCAGES EXPLICITES 99
Modes X SRX S RX RS
Commandes
LOCK EXCLUSIVE (X) non non non non non
LOCK ROW SHARE EX- non non non non OUI
CLUSIVE (SRX)
LOCK SHARE (S) non non OUI non OUI
LOCK ROW EXCLUSIVE non non non OUI OUI
(RX)
LOCK ROW SHARE (RS) non OUI OUI OUI OUI
INSERT DELETE UP- non non non OUI * OUI *
DATE
SELECT FOR UPDATE non OUI * OUI * OUI * OUI *
* à condition que l'on ne travaille pas sur des lignes déjà bloquées par
une autre transaction.
Index
ABS, 48 DATE, 7
accès concurrents, 86 date du jour, 29
ACID, 22 DECODE, 53
ajouter une colonne, 60 DEFAULT, 12
ALTER TABLE, 60 DELETE, 22
AND, 33 DESC, 54
annuler une transaction, 23 dictionnaire de données, 81
ASCII, 50 diérer des contraintes, 16
AVG, 45 DISTINCT, 45
division, 42
BETWEEN, 32 donner des droits d'accès, 82
bloquer des données, 98
DROP INDEX, 68
DROP VIEW, 64
case, 51
DUAL, 4
catalogue, 59
changer son mot de passe, 83
enlever des droits d'accès, 83
CHAR, 6
EXCEPT, 55
CHR, 50
except, 55
COALESCE, 9
EXISTS, 41
colonne, 4
EXIT, 3
COMMIT, 23, 95
concaténer des chaînes, 9 fonction de choix, 51
CONSTRAINT, 12 fonction stockée, 73
contrainte d'intégrité, 12, 65, 82 fonction utilisateur, 74
COUNT, 45 fonctions arithmétiques, 48
création d'un utilisateur, 84 fonctions chaînes de caractères, 48
créer un index, 66 fonctions de groupes, 45
créer une table, 11, 59 FOREIGN KEY, 13
créer une vue, 63 FROM, 29
CREATE INDEX, 66
CREATE TABLE, 11 génération de clés primaires, 70
CREATE TABLE AS, 59 GRANT, 82
CREATE VIEW, 63 GREATEST, 48
CURRENT_DATE, 51 GROUP BY, 45
100
INDEX 101
MAX, 45 rôle, 84
MIN, 45 REFERENCES, 13
MINUS, 55 renommer une colonne, 61
minus, 55 renommer une table, 62
mise à jour avec une vue, 64 REPLACE, 49
MOD, 48 REVOKE, 83
modier des lignes, 20 ROLLBACK, 23, 95
102 INDEX
SIGN, 48 UNIQUE, 13
sous-interrogation, 38
UPDATE, 20
SQLFORMS, 2
UPPER, 49
SQRT, 48 USER, 53
user, 29
STDDEV, 45
utilisation d'une vue, 64
SUBSTR, 48
utilité des vues, 65
SUM, 45
supprimer des lignes, 21
valider une transaction, 23
supprimer un index, 68
VARCHAR, 6
supprimer une colonne, 61
VARCHAR2, 6
supprimer une table, 62
VARIANCE, 45
supprimer une vue, 64
vue, 62
synonyme, 84
synonyme public, 62 WHERE, 31
SYSDATE, 51 WITH CHECK OPTION, 64
sysdate, 29 WITH GRANT OPTION, 83
table, 3
table DUAL, 4
TO_CHAR, 48, 49
TO_DATE, 51
TO_NUMBER, 48, 50
traitement optimiste, 91
traitement pessimiste, 90
transaction, 22
TRANSLATE, 49