Documente Academic
Documente Profesional
Documente Cultură
4 rubriques d'instructions :
- Language d'administration
create user
Gestion d'utilisateur alter user
drop user
Gerer des droits Grant Donner des droits ou des groupes de droit des
utilisateurs ou groupes d'utilisateur
Revoke Retirer les droits
Gerer des groupe de droit ou d'utilisateur create role
drop role
Ensuite le serveur produit et stocke en interne un tableau de resultat contenant autant de colonne
que de champs specifi par la requette select et autant de ligne spcifie par la clause where du
select.
Le serveur renvoie ensuite au client un curseur qui permet celui-i de consulter ligne par ligne le
contenu du tableau rsultat.
Quand le client a termin de consulter le tableau resultat il ferme le curseur et permet de la sorte au
serveur de librer l'espace mmoire utilis pour stocker le tableau de rsultat.
Ex : Php
Clause select :
Syntaxe generale du select :
L'instruction select contient plusieurs clauses, certaines obligatoires, d'autres optionnelles.
Les clauses apparaissent toujours dans le mme ordre.
select ( expression 1 as alias 1, expression 2 as alias 2, ... => Colonnes du tableau de resultat
from table 1 as alias 1, table 2 as alias 2, vue 1 as alias 3, ...=> O on cherche les donnes
where condition => Filtrer les lignes de donnes
groupe by expression 1, expression 2 ,. .. => Regrouper les lignes de donnes
havinng conditions sur agrgat. => Filtrer sur opration agrgation
order by expression 1, expression 2 , .... =>Trier les lignes donnes.
Permet de definir les colonnes du tableau resultat, leur contenu et leur titre (avec alias)
Select expression 1 as titre 1, expression 2 as titre 2 , ...
- Il y autant de colonne dans le tableau resultat que d'expression dans la clause select.
- Les colonnes apparaissent dans le mme ordre que les expressions et sont souvent numrot
partir de 0.
- Le mot cl as permet de renommer le titre d'une colonne.
min(age) max(age)
18 34
Exercice :
lignefacture (numfacture#, reference#, qt)
articles( rfrence , libell, prix HT )
select sum ( qte * prixht ) as total ht , sum( qte * prixht * 1,196 ) as total ttc ...
Clause from :
Permet de specifier la liste des tables et vues dans lesquelles le serveur de BD cherche les donnes
pour effectuer la requte.
from table1 as alias 1, table2 as alias2, ...
Dans le cas de plusieurs tables mentionnes dans la clause from le serveur construit un tableau
intermdiaire rempli par le resultat du produit cartsien de tous les enregistrements de toutes les
tables figurant dans la clause.
Le serveur cr toutes les combinaisons possibles d'enregistrements pris dans toutes les tables de la
clause from.
Ex :
Articles
Rfrence libell Code cat.# Catgories
123 carte rseau INF Code cat. Libcat
Code cat. est une cl trangre qui fait rfrence une cl primaire d'une autre table, ici catgorie.
On veut ecrire la requette qui affiche la liste des articles selon : rfrence, libell, libell catgorie :
Article Catgorie
reference libell codecat codecat libcat
123 cartereseau INF INF Informatique
123 cartereseau INF ELT Electromenager
456 Memoire INF INF Informatique
456 Memoire INF ELT Electromenager
789 Lave linge ELT INF Informatique
789 Lave linge ELT ELT Electromenager
Le nombre de combinaison produite est :
nombre de ligne de la table article x nombre de ligne de la table catgorie = 3 x 2 = 6
Ce qui nous interesse est la liste des articles avec le libell et le libell de catgorie qui correspond
la catgorie de l'article.
Nous voulons retirer uniquement les lignes pour lesquel le code catgorie de la table article est gal
celui venant de la table catgorie.
Le Where nous permet de faire cette selection selon la condition mentionne dans le tableau
intermediaire gener par le produit cartsien.
Dans l'absolu le moteur de BD genere un tableau intermediaire d'un produit cartsien des tables
selectionnesmais pour ne pas utiliser trop de ressource le moteur de SGBD va s'appuyer sur les
clauses where pour limiter le nombre de donnes.
Ex :
Etudiants
Numetu nom prenom sexe section
Generer de l'information par combinaison, qui est ensuite filtr a partir d'une seule et mme table.
Clause Where
where condition
Permet de selectionner les lignes du tableau intermdiaire qui nous interessent.
Les lignes slectionns sont celles pour qui l'execution de la condition donne un resultat vrai.
La condition est constitue d'un ensemble de sous conditions lementaires spars par ds oprateurs
logiques : Ordre de priorit
and condition and condition => Operateur binaire (2 operandes) 3
or condition or condition 4
not not condition => Operateur unaire (1 operande) 2
() ( condition ) 1
Ex : Liste des tudiants de 18 22 ans
select * from etudiants
where age >= 18 and age <= 22
Condition lementaire :
- expression oprateur de comparaison expressions
- Oprateur de comparaison :
Egalit =
Differente <>
<, > , <= , >=
- Chaine de caractre : <, > , <= , >=
C'est l'ordre lexigographique qui est utilis.
- Dates : ordre temporel
- Expression :
Constante
Champ de table
Calcul
/ ! \ Mme type d'expression que la classe select sauf les agrgats sum, min, max, count
Remarques :
- Comparaison de chaine de caractre
select * from etudiants
where prenom = 'Kevin'
1) Les chaines de caractres sont dlimites par des cotes simples en SQL !
2) Attention la casse (minuscule, majuscule) avec les constantes !
select * from etudiants
where upper (prenom) = 'KEVIN' => upper() transforme les minuscule en majuscule
( ucase() avec Oracle )
- Comparaison de date
Attention au format de date utilis par le SGBD. Ils varient selon les moteurs de SGBD :
mySQL : 'YYYY-MM-DD'
Access, SQL Server : #YYYY/MM/DD#
DB2 : Calendrier julien
Il faut alors passer par des formules de convertions.
Exemple :
- La liste des etudiants dont le nom commence par la la lettre M.
select * from etudiant where nom like 'M%'
- La liste des etudiants dont le nom se termine par ING
select * from etudiant where nom like '%ING'
- La liste des etudiants dont le nom contient TOTO
select * from etudiant where nom like '%TOTO%'
- La liste des etudiants dont le nom commence par MI et se termine par MI puis 3 caractres suivi
du caractre T et se terminant par X
select * from etudiant where nom like 'MI_ _ _ T%X'
Attention : Like n'est pas une expression rgulire mais pratique pour faire une recherche
notamment. Recherche d'un article contenant quelquechose.
Le moteur de BD va examiner toutes les occurences de la tables = pas de recherche par index =>
acccelerer les recherches (comme avec l'utilisation de =)
La condition est vrai si l'expression est egale l'une des valeurs mentionnes dans la liste.
Ex : Recherche des etudiants prsent dans les sections dont le libell contient le mot
'informatique'
2 tables : Etudiants ( numetu, nom, prenom, ... codesec# ) Modle relationnel ou logique
Sections ( codesec, libsection ) de donn
select * from etudiants where codesec in ( select codesec from sections where libsection like
'%informatique%' )
La sous requete ramne la liste des codesec de toutes les dections dont le libell contient le mot
'informatique'.
Equivalent :
select etudiants.* from etudiants, sections where etudiants.codesec = sections.codesec and libsection
like '%informatique%'
etudiants.codesec = sections.codesec => Condition de jointure interne :
etudiant.* => ramene tous les champs de la table etudiant
libsection => on ne prcise la table (etudiant.) que lorsqu'il y a une ambiguit sur le champ
(1 mme champ dans 2 tables)
Parmis toutes les combinaisons gnrs je ne prend que les conditions pour lesquel la valeur de
codesec tudiants est egal la valeur de codesec sections. Plus rapide qu'avec l'oprateur in.
Remarque :
- Avec l'operateur in, la sous requette est execute pour chaque ligne ramene par la requette
principale (moins rapide)
- Une sous requette peut utiliser des champs venant de la requette principale.
Ex : Liste des tudiants presents dans les sections dont le libell de section contient le prnom de
l'tudiant
select * from etudiants where codesec in ( select codesec from sections where libesection like
'%' , prenom , '%' ) (sous MySQL) prenom provient de la table etudiants
Operateur de concatenation :
Oracle champ1 | champ2 | champ 3
MySQL champ1 , champ2 , champ 3
Remarque :
- Le plus souvent, l'operateur in est prcd d'un epression ou d'un champs et donc la sous requette
ramene une expression ou un champ.
On peut utiliser des couples ou triplet d'expression ou le champ precedent l'operateur in avec des
sous requette ramenant des couples ou tripets d'expression.
(expression1 , expression2 ) in ( select expression1 , expression2 from ... )
- Utilisation de not in :
Not in permet de chercher quelquechose qui ne figure pas dans autre chose. (c'est souvent le seul
moyen de raliser ce genre de requette.
select * from sections where codesec not in ( select codesec from tudiants );
Pas possible de faire un select * from sections where etudiants.codesec <> sections.codesec ne
ramenera rien car le produits cartsiens ne trouvera pas de combinaisons valable entre des etudiants
et des sections.
Ex : Liste des etudiants dont le libell de section est 'Management des Units Commerciales'
select * from etudiants where codesec = ( select codesec from sections where libesection =
'Management des Units commerciales' )
Dans ce cas la sous requette doit obligoirement ramener strictement une seule valeur.
Il faut absolument que la sous requette ne ramene qu'une seule valeur.
La sous requette est ici aussi xecut chaque occurence.
Oprateur exists :
L'oprateur exists s'utilise avec une sous requette. Il renvoie une valeur boolenne, qui sera vrai si la
sous requette ramene au moins une ligne et fausse sinon.
select * from etudiants where exists ( select * from noteeval where noteeval.numetu =
etudiants.numetu and year ( dateeval ) = 2012 )
Ex : On veut la liste des etudiants en SIO dont l'age est different de celui de tous les etudiants en
MUC
select * from etudiants where codesec = 'SIO' and age <> all ( select age from etudiants where
codesec = 'MUC' )
=> Avec all la condition est vrai si l'application de l'oprateur de comparaison prcdant all est vrai
pour chaque occurrence de la sous requette.
=> Avec any la condition est vrai si l'application de l'oprateur de comparaison precedant any est
vrai pour au moins une occurence de la sous requette.
Ex : Liste des tudiants de SIO ayant un age existant parmis ceux de MUC.
select * from etudiants where codesec='SIO' and age = any ( select age from etudiants where
codesec='MUC' )
Clause group by :
syntaxe : groupe by expression1 , expression2 , ....
Le produit cartsien des tables cites dans la clause from produit un tableau intermediaire de ligne.
Celles-ci sont ensuite filtres par la condition de la clause where et enfin on peut oprer un
regroupement des lignes restantes avec la clause groupe by.
Le regroupement se fait sur des valeurs distinctes de la premiere expression (expression1 ). Les
lignes ayant la mme valeur pour l'expression1 subissent ensuite un regroupement interne selon les
valeurs distinctes de la deuxieme expression, et ainsi de suite.
Ex : Regroupement des etudiants par nom puis pour un mme nom par prnom
select * from etudiants groupe by nom , prenom
Remarque :
- Les paquets de lignes avec le mme nom mais elles ne sont pas tris.
- L'utilisation des oprations d'agrgat dans un select : min, max, sum, count, avg est calcul par
dfaut sur l'ensemble des lignes du tableau intermdiaire issus de l'xecutuion de la clause where.
La prsence d'une clause groupe by fait en sorte que le calcul des oprations d'agrgat s'effectue sur
des regroupements de ligne et non sur la totalit des lignes.
Ex : Exemple classique :
On veut la liste des sections; codesec ; libsection avec le nombre d'tudiants par section.
Comme on compte des tudiants on s'arrange pour obtenir un tableau intermediaire ayant autant de
ligne que d'tudiants.
De cette manire il suffit de compter le nombre de ligne avec un count(*)
En faisant un regroupement par codesec et par libesection on compte des lignes et donc des
etudiants par valeurs distinctes de regroupement, c'est dire par section.
Remarque :
Quand on mlange dans la clause select des expressions simples avec des oprations
! d'agrgat ( count ... ) il faut absolument regrouper en utilisant toutes les expressions
simples figurant dans le select.
Clause Having :
Syntaxe : Having condition,
- Pour des raisons d'optimisation, les oprations d'agrgats ne sont xcut qu'aprs les regoupement
de lignes.
- Ceci explique pourquoi on ne peut ecrire de conditions sur resultat d'agrgat dans la clause where
(Dans la clause where, les agrgats n'ont pas encore t calcul)
- SQL prevoit la clause having condition, qui s'executent aprs le clacul des agrgats permet d'ecrire
une condition de filtrage de ligne sur les resultats de ceux-ci.
Ex : Liste des sections avec le nombre d'tudiants mais uniquement les sections ayant plus de 5
etudiants.
select codesec, count(*) as nbetudiants from etudiants groupe by codesec having count(*) >= 5
Ex : Liste des sections avec nombre d'tudiants par section pour des sections de plus de 5
etudiants dont la moyenne d'age est comprise entre 20 et 22 ans.
select codesec, count(*) as Nbetudiant from etudiants groupeby codesec having count(*) >= 5 and
avg( age ) between 20 and 22
Remarque :
- Le tri etant gourmand en CPU, il s'effectue en dernier avec le moins de ligne possible. (consomme
bcp de ressource).
- Le tri se fait d'abord pour la premire expression puis pour la deuxime, puis pour les suivantes.
Par dfaut, celui i est selon un ordre croissant numrique, lexicographique (alphabetique) ou
temporel. Le mot desc permet de le rendre dcroissant.
- Les expressions peuvent comporter des champs, des calculs, et mme des fonctions d'agrgat ...
Exercice :
2 tables : Etudiants ( numetu, nom, prenom, age, codesec# )
Sections ( codesec, libellesec )
Ecrire les requettes suivantes :
- liste des tudiants dont le libell de section se termine par 'tique' tri par ordre croissant de nom et
ordre dcroissant de prenom.
select * from etudiants where codesec in ( select codesec from sections where libesection like
'%tique' order by nom asc, prenom desc
select * from etudiants, sections where etudiants.codesec = sections.codesec and libellesec like
'%tique' order by nom asc, prenom desc
- liste des sections : codesec, libellesec tri par moyenne d'age des etudiants
select etudiants.codesec, libellesec from etudiants, sections
where etudiants.codesec=sections.codesec
groupe by etudiants.codesec, libellesec
order by avg( age )
Exercice :
5 tables : Client ( codecli, raisoc, adresse, ville, cp )
Articles ( ref, libelle, prixht, codecat# )
Catgrorie ( codecat, libcat )
Facture ( numfact, datefact, codecli# )
Lignefact ( numfact# , ref#, qte )
4) Liste des articles, rfrence, libell, prix ht, prix ttc, avec un taux de TVA 19,6%, lib cat tri par
rfrence croissante
select libelle, articles.ref, prixht, prixht*1,196 as prix ttc, libcat from articles, catgories where
articles.codecat=categories.codecat order by ref asc
6) Liste des factures : numfact, datefact, codecli, raison sociale, ville, codepostal, total ht, total ttc
select factures.numfact, datefact, client.codecli, raisonsociale, ville, cp, sum ( qte * prixht ) as
totalht, sum( qte * prixht * 1,196 ) as totalttc
from articles, lignefact , factures, clients
where articles.ref=lignefact.ref and factures.numfact = lignesfact.numfact and
factures.codecli=client.codecli
Group By numfact, datefact, client.codeclient, raisoc, ville, cp
Exercice :
Eleves( numeleve, nom, prenom, section# )
Sections( section, libelle )
Matieres( codemat, libelle )
Notes( dateeval#, numeleve#, codemat# note )
1) Liste des lves nom, prenom, libelle de la section dont le nom commence par la lettre M tris
par ordre alphabetique inverse de prenom
2) Liste des sections avec le nombre d'eleve par section uniquement les sections auant au moins 6
leve
3) Liste de matires avec le nombre d'valuation ralises par matire sur l'anne 2012
select * from matiere where codemat not in ( select codemat from notes where year(noteval)=2012)
5) La liste des evaluations : libell de matire, date d'valuation, note moyenne, note mini, note
maxi
select libelle, dateeval, avg(note) as moyenne, min( note) as notemin, max(note) as notemax from
matiere, notes where matiere.codemat=notes.codemat groupeby libelle, dateval
select nom, prenom // La requette principale renvoi la note de l'eleve en croisant les tables
from eleve, notes // notes et eleves restreint au note obtenu par l'eleve le jour demand en math
where eleve.numeleve=notes.numeleve and dateeval='17/02/12' and codemat='math'
and note in* ( select max( note ) as notemax // La sous requette renvoi la meilleure note obtenue
from notes
where codemat='math' // pour selectionner mathematique
and dateeval='17/02/12' ) // et la date du 17/02/12
* Ici on peut aussi mettre un = puisque la sous requette renvoie une seule valeur
7) Liste des lves matiere nom, prenom et la moyenne par matiere tris par matire et par moyenne
decroissante
Ordre de transaction
Partie transactionnelle du language SQL, les requetes insert, delete, update sont appells des
transactions
INSERT
insert into table ( champ1, champ2, ...)
values (valeur1, valeur2, ... )
Attention : Ne pas utiliser la forme insert into table values (valeur1, valeur2, ... ) car les champs
peuvent tre melangs
DELETE :
delete from table where conditions
UPDATE :
update table set champ1=expression1, champ2=expression2, ...
where condition
User A User B
update personnes set prenom = 'Charles'
value matricule = '1234'
select * from personnes where matricule = 1234; select * from personnes where matricule = 1234;
=> Resultat : Charles => Resultat : Claude
Tant qu'il n'y a pas de concurent la transaction n'est pas effectue
commit;
select* from peronnes where matricule = 1234; select* from peronnes where matricule = 1234;
=> Resultat : Charles => Resultat : Charles
Cas 2 :
Table : personnes (matricule, prenom)
Enregistrement matricule 1234, prenom Claude
User A User B
update prenom set prenom='Charles' where
matricule = 1234;
select * from personnes where matricule = select * from personnes where matricule =
1234; '1234'
=> Charles => Claude
update personnes set prenom ='Henri'
where matricule = 1234
Verrou sur l'enregistrement 1234 Blocage de la transaction cause du verrou
pos sur cet enregistreur par la transaction
=> Charles non valide du UserA
Transaction en attente cause du verrou
commit; Le verrou est lev Le verrou tant lev, la transaction est
passe
=> Charles Nouveau verrou pos par la transaction de
User B
commit; Le verrou est lev
=> Henris => Henris
Client Factures
codecli nom prenoms numfact datefact codecli#
1 Meyer Charles 123 10/12/11 2
2 Dupond Henris 456 25/02/12 3
3 Durant Stephane 789 10/05/12 2
1) Il faut absolument que le champ codecli de client identifie un seul client de manire unique.
On parle d'identifiant et plus particulirement dans un schma relationel de cl primaire.
Les champs constituant la cl primaire sont soulign.
Le SGBD va alors refuser d'avoir 2 entre dans la table avec le mme codecli.
Les cl primaire sont l pour garantir l'unicit des enregistrement et permettre de referencer les
enregistrements.
Si le codecli n'est pas renseign la valeur sera NULL mais cela ne posera pas de problme
Par contre si le codecli fait reference un client qui n'existe plus ou a t supprim, il va y avoir un
probleme d'intgrit des donnes :
L'ide est de demander au SGBD de verifier si le codecli qu'on associe dans la table facture fait
reference un client existant et inversement si une requete de suppression de client devra tre
interdite pour ceux dont le codecli est associ un enregistrement de la table facture.
On pose alors une contrainte d'intgrit de rfrence :
Le SGBD va alors refuser les requetes update, delete, insert qui ne respecte pas cette contrainte
Garantie qu'il n'existera pas de factures associs des codecli qui n'existe pas.
RQ : Ces contraintes sur MySQL ne seront actives qu'avec le moteur de base de donnes INNODB.
On peut rajouter une option "on update cascade" qui va faire en sorte que s'il y a une modification
du codecli d'un client, les valeurs du champs codecli de la table factures rattach ce client seront
egalement modifi :
4) alter table factures add constraint factures_fk1 foreign key( code cli)
references clients(codecli) on update cascade
Requete pour modifier le codecli du client :
update clients set codecli=6 where codcli=2;
RQ : Existe egalement l'option "on delete cascade" qui va supprimer toutes les factures li au client
Attention dangereux !
L'ide est de ne pas pouvoir crer 2 lignes differentes dans une mme factures faisant reference un
meme article.
- On met alors les 2 cl etrangres numfact et reference en cl primaires
- On mettra egalement 2 contraintes d'intgrit de reference pos sur le champ reference et numfact
de ligne facture faisant reference au champs correspondant dans les tables articles et factures.
- Enfin on mettra egalement une option on update cascade pour modifier toutes les references d'un
article dans lignefact lorsqu'une modification est faite sur un article partir de la table article.
- On mettra une option on delete cascade entre la facture et les lignesfactures : on peut dire que la
facture est "propritaire" des lignes de factures qui lui sont associs, la suppression est l logique
Au travers de l'instruction CREATE VIEW il est possible d'enregistrer dans la base de donnes une
requette SELECT
Celle-i pourra ensuite tre utilis dans un autre SELECT comme s'il s'agissait d'une table.
Exemple :
Remarque :
Clich : requete associ une table et qui s'execute rgulierement pour raccourcir le temps
d'execution en ne rxecutant pas la requete SQL.