Vous êtes sur la page 1sur 58

‭Technicien en Techniques de Développement Informatique‬

‭Guide des cours‬

‭Module 201 ‬‭: (I)‬

‭Requêtes‬

‭SQL Server 2017‬

‭Hamid Mask‬
‭Formateur en TDI‬

‭1‬‭/‬‭57‬
‭https://sql.sh/fonctions/agregation/max‬

I‭mplémentation‬
‭d’une base de données‬

‭2‬‭/‬‭57‬
‭https://sql.sh/fonctions/agregation/max‬

‭I - Système de Gestion de Bases de Données Relationnel‬


‭(SGBDR).‬
‭ e langage SQL a été initialement conçu dans les années 1970 par la firme IBM. Il a été‬
L
‭ensuite normalisé et est devenu le standard de tous les‬‭SGBDR‬‭(‭S ‬ ‬‭ystème de‬‭G‭e
‬ stion de‬
‭B‬‭ases de‬‭D‭o‬ nnées‬‭R‬‭elationnel).‬
‭En alglais :‬‭RDBMS‬‭(‬‭R‬‭elational‬‭D‬‭ata‬‭B‭a
‬ se‬‭M‬‭anagement‬‭S‭y‬ stem).‬

‭ n‬‭SGBDR‬‭est un logiciel qui permet :‬


U
‭– la définition des données : création des tables, des contraintes, des relations etc. ;‬
‭– la manipulation des données : sélectionner, insérer, supprimer et modifier ;‬
‭– la sécurité des données ;‬
‭– la programmation : Procédures Stockées, Fonctions, Triggers et Curseurs. (Transact-SQL)‬

‭Remarque :‬
‭ n SGBDR offre :‬
U
‭ ‬ ‭Un‬‭LDD‬‭=‬‭L‭a
● ‬ ngage de‬‭D‬‭escription des‬‭D‬‭onnées ou‬‭DDL‬‭en anglais.‬
‭Exemples de commandes LDD :‬
‭CREATE DATABASE - ALTER DATABASE - CREATE TABLE -‬
‭ALTER TABLE - DROP TABLE - CREATE INDEX - DROP INDEX.‬

‭●‬ ‭Un‬‭LMD‬‭=‬‭L‬‭angage de‬‭M‭a


‬ nipulation des‬‭D‬‭onnées ou‬‭DML‬‭en anglais‬
‭Exemples de commandes LMD :‬
‭SELECT - INSERT - UPDATE - DELETE -.‬

‭II - Création d’une base de données :‬


‭Dans SQL Server Management Studio, on peut travailler :‬
‭●‬ ‭Soit avec l’assistant (Boites de dialogue)‬‭🡪‬‭Très‬‭facile à utiliser.‬
‭●‬ ‭Soit en écrivant du code SQL dans un fichier .sql (appelé script).‬

‭II - 1 Une base et son journal :‬

‭ ne base de données SQL Server contient au minimum :‬


U
‭–‬ ‭un fichier de données principal (d’extension .mdf) où sont stockées les données ;‬
‭–‬ ‭un‬ ‭journal‬ ‭des‬ ‭transactions‬ ‭(d’extension‬ ‭.ldf)‬ ‭où‬ ‭sont‬ ‭répertoriées‬ ‭toutes‬ ‭les‬
‭transactions.‬

‭II - 1 - 1 Création de la base de données Vente‬

‭Schema de la BD‬

‭3‬‭/‬‭57‬
‭ REATE‬‭DATABASE‬‭Vente‬
C ‭🡪‬‭le nom de la base‬
‭ON‬‭PRIMARY‬ ‭🡪‬‭le fichier de données principal‬
‭(‬
‭NAME‬‭= Vente_data ,‬ ‭🡪‬‭nom logique‬
‭FILENAME‬‭= ‘C:\Data\vente.mdf’ ,‬ ‭🡪‬‭chemin et‬‭nom du fichier (nom physique)‬
‭SIZE‬‭= 60MB ,‬ ‭🡪‬ ‭taille de départ‬
‭MAXSIZE‬‭= 70MB ,‬ ‭🡪‬‭taille maximale‬
‭FILEGROWTH‬‭= 1MB‬ ‭🡪‬‭increment‬
‭)‬
‭LOG‬‭ON‬ ‭🡪‬‭le journal‬
‭(‬
‭NAME‬‭= Vente_log ,‬
‭FILENAME‬‭= ’D:\Log\vente.ldf’,‬
‭SIZE‬‭= 15MB ,‬
‭MAXSIZE‬‭= 20MB ,‬
‭FILEGROWTH‬‭= 1MB‬
‭)‬

‭Ou tout simplement :‬ ‭CREATE‬‭DATABASE‬‭Vente‬

‭II - 1 - 2 Modification du nom d’une base de données existante :‬

‭ALTER‬‭DATABASE‬‭Vente‬‭MODIFY‬‭NAME‬‭= Commerce‬

‭II - 1 - 3 Suppression d’une base de données :‬

‭DROP‬‭DATABASE‬‭Vente‬

‭II - 2 Création des tables :‬


‭Creation de la table Client‬

‭ reate‬‭Table‬‭Client‬
C
‭(‬
‭CodeCl‬‭int‬‭Primary‬‭Key‬‭,‬
‭Nom‬‭Varchar‬‭(40)‬‭Not Null‬‭,‬ ‭🡪‬‭Obligatoire‬
‭Ville‬‭Varchar‬‭(30)‬ ‭🡪‬‭Non oblgatoire‬
‭)‬

‭4‬‭/‬‭57‬
‭Creation de la table Article‬

‭ reate‬‭Table‬‭Article‬
C
‭(‬
‭CodeArt‬‭int‬‭Primary‬‭Key‬‭,‬
‭Desi‬‭Varchar‬‭(40),‬
‭PU‬‭Money‬‭,‬
‭Qdisp‬‭int‬
‭)‬

‭🡺‬ ‭NULL‬ ‭= pas d’information.‬

‭🡪‬‭Remplissage de la table Client‬

‭Insert into Client values (1,'Alami','Fès'),‬


‭(2, 'Safar','Casa'),‬
‭(3,'Naji','Fès'),‬
‭(4,Wahbi,'Rabat')‬

‭Select * from Client‬

‭🡪‬‭Remplissage de la table Article‬

‭Insert into Article values (1,'PC', 4000,10),‬


‭(2,'Imprimante',2000,20),‬
‭(3,'Disque',500,30),‬
‭(4,'Scannerr', 1500,40)‬

‭Select * from Article‬

‭Pour modifier une table existante, on utilise l’instruction ALTER TABLE.‬

‭●‬ ‭pour ajouter la colonne adresse‬

‭ALTER TABLE Client ADD Adresse Varchar(60)‬

‭●‬ ‭Pour retirer la colonne adresse‬

‭ALTER TABLE Client DROP COLUMN Adresse‬

‭●‬ ‭Pour reconvertir le type d’une colonne (champ) :‬

‭ALTER TABLE Client ALTER COLUMN CodeCl INT‬

‭●‬ ‭Pour renommer une table‬‭:‬

‭EXEC sp_rename‬‭'Client' , 'Customer'‬

‭●‬ ‭Pour supprimer une table existante‬‭:‬

‭DROP TABLE client‬

‭5‬‭/‬‭57‬
‭II – 3 Les différents types de données.‬

‭‬ C
● ‭ har, nchar, varchar, nvarchar‬
‭●‬ ‭int, bigint, smallint, tinyint, decimal / numeric, float, real, money,‬
‭smallmoney‬

‭‬
● ‭ ate, datetime, datetime2, smalldatetime, datetimeoffset, time‬
D
‭●‬ ‭Geometry, geography‬
‭●‬ ‭Uniqueidentifier, rowversion‬
‭●‬ ‭binary, varbinary, bit‬
‭●‬ ‭xml‬

‭II – 4 Numérotation automatique :‬


‭ our la clé primaire d’une table, il est souvent préférable de laisser SQL Server générer des‬
P
‭valeurs distinctes.‬

‭Create Table Client‬


‭(‬
‭CodeCl INT Primary Key IDENTITY(1,1) ,‬
‭Nom Varchar(40) Not Null,‬
‭Ville Varchar(40)‬
‭)‬

‭IDENTITY(Seed,Incr)‬ ‭Seed‬‭: la valeur de départ‬


‭Incr‬ ‭:‬‭le pas d’incrément‬

‭IDENTITY(1,1) ou IDENTITY‬‭🡪‬ ‭1, 2, 3, 4, . . .‬

‭IDENTITY(4,2)‬ ‭🡪‬ ‭4, 6, 8, 10, . . .‬

‭6‬‭/‬‭57‬
‭Exemple‬‭:‬

‭ reate Table Customer‬


C
‭(‬
‭CodeCl INT Primary Key IDENTITY(10,2) ,‬
‭Nom Varchar(40) Not Null,‬
‭Ville Varchar(40)‬
‭)‬

‭🡪‬‭Remplissage de la table Client‬

‭Insert into Customer (Nom,Ville) values('Alami','Fès'),‬


‭('Safar','Casa'),‬
‭('Naji','Fès'),‬
‭('Wahbi','Rabat')‬

‭Select * from Customer‬

‭Insert into Customer (Nom,Ville) values('eee','Casa')‬

‭Select @@IDENTITY As [@@IDENTITY]‬

‭🡪‬

‭●‬ ‭SET IDENTITY_INSERT … ON‬‭: désactive l’usage de la‬‭propriété IDENTITY‬

‭SET IDENTITY_INSERT Customer ON‬

‭Insert into Customer (CodeCl,Nom,Ville) values(25,'ggg','Fés')‬

‭Select * From Customer‬

‭●‬ ‭SET IDENTITY_INSERT … OFF‬‭: réactive l’usage de‬‭la propriété IDENTITY‬

‭SET IDENTITY_INSERT Customer OFF‬

‭7‬‭/‬‭57‬
‭Insert into Customer (Nom,Ville) values('xxx','Safi')‬

‭Select @@IDENTITY As [@@IDENTITY]‬

‭🡪‬

‭Select * from Customer‬ ‭🡪‬

‭●‬ ‭Pour connaître‬‭la valeur de départ‬‭fixée lors de la‬‭création du type identity.‬

‭Select IDENT_SEED(‘Customer’) As [IDENT_SEED]‬

‭🡪‬

‭●‬ ‭Pour connaître‬‭le pas d’incrément‬‭de la valeur identity.‬

‭Select IDENT_INCR(‘Customer’) As [IDENT_INCR]‬

‭🡪‬

‭●‬ I‭DENT_CURRENT (’nom_table’) Retourne‬‭la dernière valeur‬‭de type identité‬


‭utilisée par cette table.‬
‭Select IDENT_CURRENT(‘Customer’) As [IDENT_CURRENT]‬

‭🡪‬

‭●‬ @
‭ @IDENTITY Enregistre‬‭la dernière valeur IDENTITY‬‭insérée.‬
‭Select @@IDENTITY As [@@IDENTITY]‬

‭🡪‬

‭II – 5 Champs calculés‬

‭●‬ ‭Exemple‬‭1 :‬

‭ lter Table Article‬


A
‭ADD ValeurStock As Qdisp*PU‬

‭Select * From Article‬

‭8‬‭/‬‭57‬
‭🡪‬

‭ lter Table Article‬


A
‭DROP COLUMN ValeurStock‬

‭Remarque‬‭: L’expression du champ calculé ne doit pas‬‭contenir un fonction‬


‭d’aggrégation (Sum, Count, …).‬

‭●‬ ‭Exemple‬‭2 :‬

‭ reate Table Facture‬


C
‭(‬
‭FactureID int Primary Key IDENTITY,‬
‭HT Money Not Null,‬
‭TVA As HT*0.2,‬
‭TTC As HT + HT*0.2‬
‭)‬

‭Insert Into Facture(HT) Values‬ ‭


(‬100‬
‭ ),(‬
‭ 200‬
‭ )‬

‭Select * From Facture‬ ‭🡪‬

‭III - Sélectionner les données‬


‭III – 1 Séléction simple‬

‭●‬ ‭Les clients de Fès :‬

‭Select * From Client Where Ville = ‘Fès’‬

‭●‬ ‭Where :‬

‭Select * From Client Where‬‭Nom = ’Alami’‬

‭ here Nom Like ’Alami’‬


W
‭Where Nom <> ’Alami’‬
‭Where Nom Not Like ’Alami’‬

‭ here Ville IN (’Fès’, ’Rabat’, ’Casa’)‬


W
‭Where Ville NOT IN (’Fès’, ’Rabat’, ’Casa’)‬

‭ here Nom LIKE ’A%’‬ ‭🡪‬ ‭Commence par la lettre‬‭A‬


W
‭Where Nom LIKE ’R_CHDI’‬ ‭🡪‬‭la 2eme lettre est‬‭quelconque‬
‭Where Nom LIKE ’%[M-R]’‬ ‭🡪‬‭se termine par M‬‭ou N ou O jusqu’à‬
‭R.‬
‭Where Nom LIKE ’%P%’‬ ‭🡪‬ ‭Contient la letter‬‭P‬
‭Where Nom LIKE ’%‬‭^‭[‬FMR]’‬ ‭🡪‬‭Ne se termine ni‬‭par F, ni par M ni‬
‭par R‬

‭9‬‭/‬‭57‬
‭Where Age BETWEEN 20 AND 40‬ ‭🡪‬‭Age entre 20 et‬‭40‬

‭On peut utiliser‬‭:‬

‭ OT IN‬
N
‭NOT LIKE‬
‭NOT BETWEEN‬

‭●‬ ‭Les Alias‬‭:‬ ‭On peut utiliser des noms d’alias pour‬‭les colonnes :‬

‭Select CodeCl As [Numéro Client], Nom As NomClient, Ville From Client‬

‭●‬ ‭Tri des résultats‬‭:‬

‭Select * From Client Order By Ville Desc, Nom Asc‬

‭Identique à :‬

‭Select * From Client Order By 3 Desc, 2 Asc‬

‭●‬ ‭Distinct : pour éviter les doublons‬

‭Select Distinct Nom, Ville From Client‬ ‭🡪‬ ‭Nom une‬‭fois par ville‬

‭●‬ ‭TOP‬‭:‬

‭Select Top 10 * From Client Where Ville = ’Fès’‬

‭Select Top 50 percent * From Client Where Ville = ’Fès’‬

‭Syntaxe d’une requête select :‬


‭ ELECT‬‭colonnes‬
S
‭FROM‬‭Tables‬
‭WHERE‬‭conditions‬
‭ORDER BY‬‭colonnes‬

‭IV - Quelques fonctions SQL‬

‭A tout moment dans une requête SELECT on peut utiliser de nombreuses fonctions.‬

‭IV – 1 Fonctions d’agrégation.‬

‭ OUNT‬
C ‭🡪‬ ‭le nombre‬
‭SUM‬
‭MIN‬
‭MAX‬
‭AVG‬ ‭🡪‬ ‭moyenne‬

‭Exemple :‬

‭1.‬ ‭Calculer le nombre de clients de Fès.‬

‭10‬‭/‬‭57‬
‭Select Count (CodeCl) From Client Where Ville = ‘Fès’‬

‭elect‬‭
S Count‬(‬
‭ CodeCl‬
‭ )‬‭
‭ As‬‭
NbClients‬‭ From‬‭
Client‬
Select‬‭
‭ AVG‬
(‬
‭ PU‬
‭ )‬‭
‭ As‬‭
PUmoy‬‭From‬‭ Article‬
Select‬‭
‭ Min‬
(‬
‭ PU‬
‭ )‬‭
‭ As‬‭
PUmin‬,‭
‭M‬ax‬
(‭
‭P‬U‬
)‬‭
‭ As‬‭
PUmax‬‭
From‬‭
Article‬

‭2.‬ ‭Nombre de Clients par ville.‬


‭Select‬‭Ville,‬‭Count‬‭(CodeCl) As NombreClients‬
‭From‬‭Client‬
‭Group B‬‭y Ville‬

‭IV – 1 Fonctions Dates.‬

‭✔‬ Y ‭ ear‬‭( UneDate )‬ ‭🡪‬ ‭retourne l’année‬


‭Month‬‭( UneDate )‬ ‭🡪‬ ‭retourne le mois‬
‭Day‬‭( UneDate )‬ ‭🡪‬ ‭retourne le jour‬

‭Exemple‬
‭Select‬‭Day‬‭(‬‭GetDate‬‭())‬‭As‬‭Jour‬‭,‬‭Month‬‭(‭G
‬ etDate‬‭())‬‭As‬‭Mois‬‭,‬‭Year‬‭(‬‭GetDate‬‭())‬‭As‬‭Année‬

‭✔‬ ‭DATEDIFF‬‭( Year , Date-Debut, Date-Fin)‬ ‭🡪‬‭Retourne‬‭la différence‬


‭(Date-Fin - Date-Debut) en années.‬

‭Month, Week, Day, Hour, minute ou second.‬

‭Exemple 1 :‬
‭Select DateDiff(Year, ‘06/10/2012’, ‘06/02/2014’) 🡪‬ ‭Résultat : 2‬

‭Exemple 2 :‬
‭Select DateDiff(Month, ‘06/10/2013’, ‘06/02/2014’)‬ ‭🡪‬ ‭Résultat : 4‬

‭✔‬ ‭DATEADD‬‭( Year, 4 , UneDate )‬ ‭🡪‬‭Ajoute 4 à l’année‬‭de la date UneDate‬


‭JJ / MM / AAAA+4‬
‭Month‬ ‭🡪‬ ‭JJ / MM +4 / AAAA‬
‭Day‬ ‭🡪‬ ‭JJ+4 / MM / AAAA‬
‭Hour, Minute , Second‬

‭Exemple :‬
‭DateAdd(Year, 4, ‘06/10/2014’)‬ ‭🡪‬ ‭06/10/2018‬

‭✔‬ ‭DATEPART‬‭(Month, UneDate)‬ ‭🡪‬ ‭le numéro du mois‬

‭Exemple :‬
‭DATEPART(Month, 06/10/2014)‬ ‭🡪‬ ‭10‬

‭11‬‭/‬‭57‬
‭Exercice 1 :‬
‭Eleve‬‭(CodeE, Nom, Prenom, Date-Naiss)‬
‭On veut calculer et afficher l’âge pour chaque élève.‬

‭Select Nom, DateDiff(Year, Date-Naiss, GetDate()) As Age From Eleve‬

‭Exercice 2‬‭:‬‭Cas Biblio‬

‭1-‬ O
‭ n veut calculer et afficher le retard au-dela de 15 jours pour chaque emprunt non‬
‭encore retourné.‬

‭2-‬ O
‭ n veut calculer et afficher pour chaque adhérent le cumul (la somme) des retards de‬
‭tous ses emprunts non encore retourné.‬

‭ elect CodeA, CodeL, DateEmp, (DateDiff(Day, DateEmp,GetDate()) – 15) As Retard‬


S
‭From Emprunt Where DateRetour = Null And Retard > 0‬

‭Select CodeA, Sum(DateDiff(Day, DateEmp,GetDate()) – 15) As CumulRetard‬


‭ rom Emprunt Where DateRetour = Null And‬
F
‭DateDiff(Day, DateEmp,GetDate()) – 15> 0‬
‭Group By CodeA‬

‭●‬ ‭Insertion‬

I‭nsert Client Values (’Cl01’, ’aaa’, ’Fès’)‬


‭Insert Client(CodeCl,Nom) Values (’Cl02’, ’bbb’)‬

‭ opie la table Client1 dans la table Client.‬


C
‭Insert Into Client Select * From Client1‬

‭●‬ ‭Supposons la table commande avec la structure suivante :‬

‭ reate Table Commande‬


C
‭(‬
‭NumCom INT Primary Key,‬
‭DateCom Date Default GetDate(),‬
‭CodeCl Varchar(6) Foreign key references Client(CodeCl)‬
‭)‬

I‭nsert Commande (CodeCl) Values (’Cl01’)‬ ‭‬


1 ‭ 5/11/2016‬
1 ‭ l01‬
C
‭Insert Commande (CodeCl) Values (’Cl02’)‬ ‭2‬ ‭15/11/2016‬ ‭Cl02‬

‭●‬ ‭Suppression‬

‭ elete Client Where Ville = ‘Fès’‬


D ‭🡪‬‭supprimer les‬‭clients de Fès‬
‭Delete Client‬ ‭🡪‬ ‭Vider la table‬

‭Truncate‬‭Table‬‭Client‬ ‭🡪‬ ‭Vider la table‬

‭12‬‭/‬‭57‬
‭ a‬ ‭différence‬ ‭notable‬ ‭entre‬ ‭les‬ ‭commandes‬ ‭Delete‬ ‭et‬ ‭Truncate‬ ‭est‬ ‭que‬ ‭la‬
L
‭commande‬‭TRUNCATE‬‭va ‬‭ré-initialiser‬‭la‬‭valeur‬‭de‬‭l’auto-incrément‬‭,‬‭s’il‬‭y‬‭en‬
‭a un.‬

‭●‬ ‭Modification‬

‭Update Client Set Nom = ’Ali’ Where Codecl = ’Cl01’‬

‭Update Article Set PU = PU * 0.9 Where Qdisp >= 100 (PU = PU – PU*0.1)‬
‭🡪‬ ‭reduire‬ ‭le‬ ‭PU‬‭de‬‭10%‬‭pour‬‭tous‬‭les‬‭articles‬‭dont‬‭la‬‭quantité‬‭en‬‭stock‬
‭est supérieure à 100.‬

‭Syntaxe générale avec jointures multiples :‬

‭ elete‬‭Table1‬
D
‭From‬‭Table1 a‬
‭Join‬‭Table2 b On ……‬
‭Join‬‭Table3 c On …….‬
‭Where‬‭Ch2 = …. And Ch3 = ….‬

‭Update‬‭Table1 Set Ch1 = ….‬


‭ rom‬‭Table1 a‬
F
‭Join‬‭Table2 b On ……‬
‭Join‬‭Table3 c On …….‬
‭Where‬‭Ch2 = …. And Ch3 = ….‬

‭Avec -‬‭Ch1 : Champ de Table1‬


‭-‬‭Ch2 : Champ de Table2‬
‭-‬ ‭Ch3 : Champ de Table3‬

‭IV - Définir les relations :‬

‭-- Creation de la table Commande‬

‭ reate Table Commande‬


C
‭(‬
‭NumCom Int Primary Key,‬
‭DateCom Date Default GetDate(),‬
‭CodeCl Int Foreign key references Client(CodeCl)‬
‭)‬

‭-- Creation de la table Detail‬

‭ reate Table Detail‬


C
‭(‬
‭NumCom Varchar(6) Foreign key references Commande (NumCom),‬
‭CodeArt Varchar(6) Foreign key references Article (CodeArt),‬
‭Qte int‬
‭Constraint Pk_Detail‬

‭13‬‭/‬‭57‬
‭Primary Key (NumCom,CodeArt)‬
‭)‬

‭-- Remplissage de la table Commande‬

‭Insert into Commande values (1,'10/10/2016','Cl01'),‬


‭(2,'20/10/2016','Cl01'),‬
‭(3,'10/11/2016','Cl02'),‬
‭(4,'20/11/2016','Cl03')‬
‭Insert into Commande(NumCom,CodeCl) values (5,'Cl04')‬

‭Select * from‬ ‭Commande‬

Set‬‭
‭ DateFormat‬‭
dmy‬

‭-- Remplissage de la table Detail‬

‭Insert into Detail values ('C01','A01',10),‬


‭('C01','A02',20),‬
‭('C01','A03',30),‬
‭('C02','A01',10),‬
‭('C02','A02',20),‬
‭('C03','A03',10)‬

‭Select * from Detail‬

‭Select * From Client where Ville='Fès'‬

‭Select Nom From Client‬

‭Syntaxe générale d’une requête select :‬


‭ ELECT‬‭[‭D
S ‬ ISTINCT‬‭] [‬‭TOP‬‭(n)]‬‭colonnes‬
‭FROM‬‭Table1‬
‭JOIN‬‭Table2‬ ‭ON‬‭condition‬‭de‬‭jointure‬
‭JOIN‬‭. . .‬
‭WHERE‬‭conditions‬
‭GROUP BY‬‭colonnes‬
‭HAVING‬‭conditions‬
‭ORDER BY‬‭colonnes‬

‭14‬‭/‬‭57‬
‭Exercices‬
‭Requêtes SQL – Série N° 1‬

‭Soit la Base de données‬‭Vente‬‭:‬

‭Créer les requêtes suivantes permettant de :‬

1‭ .‬ ‭Sélectionner les clients de la ville de Fès.‬


‭2.‬ ‭Sélectionner les clients dont les noms commencent par ‘HA’.‬
‭3.‬ ‭Afficher les clients par ordre alphabétique selon le nom.‬
‭4.‬ ‭Sélectionner les commandes passées entre deux dates.‬
‭5.‬ ‭Sélectionner les commandes d'un client donné dont on connaît le nom.‬
‭6.‬ ‭Sélectionner les commandes des clients de la ville de Fès.‬
‭7.‬ ‭Calculer le nombre de commandes d'un client donné (par son nom).‬
‭8.‬ ‭Calculer le nombre de commandes par ville.‬
‭9.‬ ‭Calculer le montant des lignes d'une commande.‬‭(Afficher‬‭les lignes de‬
‭commande)‬
1‭ 0.‬ ‭Calculer le total d’une commande.‬
‭11.‬‭Calculer le total pour chaque commande.‬
‭12.‬ ‭Calculer le total des totaux des commandes d’un client (Chiffre‬
‭d’affaire d’un client).‬
‭13.‬ ‭Calculer le Chiffre d’affaire pour chaque client.‬

‭15‬‭/‬‭57‬
‭Exercices‬
‭Requêtes SQL – Série N° 2‬

‭Soit le schéma de la base de données‬‭Biblio‬‭:‬

‭ bExmplaire‬‭est un attribut qui permet de comptabiliser‬‭le nombre‬


N
‭d’exemplaires restant dans la bibliothèque d’un livre donné.‬
‭DateRetour‬ ‭est nul à l’emprunt et sera mise à jour‬‭au retour du livre.‬

‭Travail demandé :‬

‭ .‬ ‭Lister l’ensemble des livres triés par ordre croissant selon le titre.‬
1
‭2.‬ ‭Lister les livres par thème.‬
‭3.‬ ‭Calculer le nombre de livres par thème trié par ordre croissant selon ce‬
‭nombre.‬
‭4.‬ ‭Calculer le nombre d’emprunts par adhérent.‬
‭5.‬ ‭Calculer le nombre de livres emprunté par adhérent.‬
‭6.‬ ‭Calculer le nombre d’emprunts par livre.‬
‭7.‬ ‭Calculer le nombre d’emprunts par thème.‬
‭8.‬ ‭Calculer le nombre d’emprunts mensuel.‬
‭9.‬ ‭Calculer le nombre d’emprunts annuel.‬
‭10.‬ ‭Sélectionner le livre le plus emprunté.‬
‭11.‬ ‭Sélectionner le thème le plus emprunté.‬
‭12.‬ ‭Sélectionner l’adhérent ayant effectué le maximum d’emprunts.‬
‭13.‬ ‭Sélectionner les emprunts après une date donnée.‬
‭14.‬ ‭Sélectionner les emprunts concernant le thème «Maths».‬
‭16‬‭/‬‭57‬
‭ 5.‬ ‭Supprimer les emprunts après une date donnée.‬
1
‭16.‬ ‭Supprimer les emprunts concernant le thème «Maths».‬
‭17.‬ ‭Mettre à jour la date de retour des emprunts d’un adhérent à la date‬
‭système.‬
‭18.‬ ‭Supprimer tous les emprunts du mois 5/2018.‬
‭19.‬ ‭Doubler le nombre d’exemplaires des livres du thème «Economie».‬
‭20.‬ ‭On veut calculer et afficher le retard au-delà de 15 jours pour chaque‬
‭emprunt non encore retourné.‬
‭21.‬ ‭On veut calculer et afficher pour chaque adhérent le cumul (la somme)‬
‭des retards de tous ses emprunts non encore retourné.‬
‭22.‬ ‭On veut calculer et afficher le retard au-delà de 15 jours pour chaque‬
‭emprunt retourné.‬
‭23.‬ ‭On veut calculer et afficher pour chaque adhérent le cumul (la somme)‬
‭des retards de tous ses emprunts retourné.‬

‭ 7- Selectionner les livres qui ne sont jamais empruntés‬


1
‭18- Selectionner les Thèmes qui ne sont jamais empruntés‬

‭17‬‭/‬‭57‬
‭V - Les Contraintes‬
‭Ce sont des conditions sur les données. On en connait déjà : les clés primaires et‬
‭ trangères, les valeurs par défaut. L’objet de cette section est d’apprendre à créer ces‬
é
‭contraintes.‬

‭V - 1 Syntaxe‬
‭Pour définir une contrainte sur une colonne d’une table, on dispose de deux syntaxes :‬

‭– Au moment de la création de la table‬

‭Create‬‭Table‬‭Client‬
‭(‬
‭CodeCl‬‭Varchar‬‭(‭6 ‬ ‬‭),‬
‭Nom‬‭Varchar‬‭(‬‭40‬‭)‬‭Not‬‭Null,‬
‭Ville‬‭Varchar‬‭(‬‭40‬‭)‬

‭ ONSTRAINT‬ ‭cst_Nom‬ ‭🡪‬ ‭nom de la contrainte‬


C
‬ om‬‭LIKE‬‭'A%'‬‭)‬ ‭🡪‬‭corps de la contrainte‬
‭CHECK‬‭(‭N

‭ ONSTRAINT‬‭cst_Ville‬
C
‭CHECK‬‭(‭V
‬ ille‬‭In‬‭(‭'‬Fès'‬‭,‬‭'Casa'‬‭,‬‭'Rabat'‬‭))‬

‭ ONSTRAINT‬‭Pk_Client‬
C
‭Primary‬‭Key‬‭(‬‭CodeCl‬‭)‬

‭ ONSTRAINT‬‭def_Ville‬
C
‭Default‬‭'Fès'‬‭For‬‭Ville‬
‭)‬

‭ emarques :‬
R
‭✔‬ ‭pour pouvoir ajouter une contrainte, les données existantes doivent vérifier cette‬
‭contrainte ;‬
‭✔‬ ‭sur insertion ou mise-à-jour, les nouvelles données sont contrôlées (si une donnée‬
‭ne vérifie pas une contrainte alors toute la transaction est annulée) ;‬
‭✔‬ ‭on peut manipuler plusieurs contraintes dans un seul ALTER TABLE, il su‬‭ffi‬‭t de les‬
‭séparer par des virgules ;‬

‭ LTER‬‭TABLE‬‭Table1‬
A
‭ADD‬‭CONSTRAINT‬‭X‬
‭CHECK‬‭(.‬‭.‬‭.),‬
‭ADD‬‭CONSTRAINT‬‭Y‬
‭CHECK‬‭(.‬‭.‬‭.),‬
‭ADD‬‭CONSTRAINT‬‭Z‬
‭CHECK‬‭(.‬‭.‬‭.)‬

‭– on peut imposer plusieurs contraintes sur une même colonne.‬

‭18‬‭/‬‭57‬
‭Pour‬‭supprimer‬‭une‬‭contrainte‬‭:‬

‭Syntaxe :‬
‭ LTER‬‭TABLE‬‭Nom de la table‬
A
‭DROP‬‭CONSTRAINT‬‭Nom de lacontrainte‬

‭Exemple :‬

‭ LTER‬‭TABLE‬‭Client‬
A
‭DROP‬‭CONSTRAINT‬‭cst_Nom‬

‭Pour‬‭modifier‬‭une contrainte, il faut d’abord la‬‭supprimer‬‭puis la recréer de nouveau.‬

‭Renommer‬‭une contrainte :‬

‭XEC‬‭
E sp_rename‬‭
N'cst_Ville'‬
,‬‭
‭ N'cst_City'‬
,‬‭
‭ N'Object'‬
EXEC‬‭
‭ sp_rename‬‭
N'cst_Nom'‬
,‬‭
‭ N'cst_Name'‬
,‬‭
‭ N'Object'‬
EXEC‬‭
‭ sp_rename‬‭
'def_Ville'‬
,‬‭
‭ 'def_City'‬
,‬‭
‭ 'Object'‬

‭V - 2 CHECK‬

‭ ‬ ‭- Syntaxe‬
1
‭La syntaxe d’une contrainte de type‬‭vérification‬‭est‬‭: CHECK (clause WHERE sans le‬
‭WHERE).‬

‭Exemples : on peut donc avec la table Personne(CodeP,Nom,Prenom,Civil,Age)‬

‭✔‬ ‭mettre plusieurs conditions :‬

‭ LTER‬‭TABLE‬‭Personne‬
A
‭ADD‬‭CONSTRAINT‬‭cst_age‬
‭CHECK‬‭(‭a
‬ ge‬‭>=‬‭0‬‭AND‬‭age‬‭<‬‭150‬‭)‬

‭✔‬ ‭préciser une liste de choix desquels on ne peut pas sortir :‬

‭ LTER‬‭TABLE‬‭Client‬
A
‭ADD‬‭CONSTRAINT‬‭cst_Ville‬
‭CHECK‬‭(‭V
‬ ille‬‭In‬‭(‭'‬Fès'‬‭,‬‭'Casa'‬‭,‬‭'Rabat'‬‭))‬

‭✔‬ ‭utiliser plusieurs colonnes‬

‭ LTER‬‭TABLE‬‭Emprunt‬
A
‭ADD‬‭CONSTRAINT‬‭cst_DateEmp_DateRet‬
‭CHECK‬‭(‭D
‬ ateEmp‬‭<‬‭DateRetour‬‭)‬

‭Remarques‬‭: par contre‬


‭ ‬ l‭a clause CHECK ne peut pas contenir de sous-requête (Requête Select).‬
‭⮚‬ ‭la clause CHECK ne peut pas porter sur une colonne utilisant IDENTITY.‬

‭V - 3 Valeur par défaut‬


‭19‬‭/‬‭57‬
‭Valeur prise par défaut par une colonne lorsque l’utilisateur ne fournit pas de valeur‬
‭pour cette colonne à l’insertion.‬

‭Exemple :‬
‭ LTER‬‭TABLE‬‭Client‬
A
‭ADD‬‭CONSTRAINT‬‭def_Ville‬
‭Default‬‭'Fès'‬‭For‬‭Ville‬

‭Pour la table Commande :‬

‭✔‬ ‭Lors de la création :‬

‭ reate‬‭Table‬‭Commande‬
C
‭(‬
‭NumCom‬‭Varchar‬‭(‬‭6‭)‬ ‬‭Primary‬‭Key‬‭,‬
‭DateCom‬‭Date‬‭Default‬‭GetDate‬‭(),‬
‭CodeCl‬‭Varchar‬‭(‭6
‬ ‬‭)‬‭Foreign‬‭key‬‭references‬‭Client‬‭(‬‭CodeCl‬‭)‬
‭)‬

‭✔‬ ‭Après la création :‬

‭ LTER‬‭TABLE‬‭Commande‬
A
‭ADD‬‭CONSTRAINT‬‭def_DateCom‬
‭DEFAULT‬‭GETDATE‬‭()‬‭FOR‬‭DateCom‬

‭V - 4 Clé primaire‬

‭Les clés primaires sont aussi des contraintes et pour les ajouter lors de la création de la‬
‭table, on peut utiliser la syntaxe :‬

‭ ONSTRAINT‬‭nom‬‭de‬‭la‬‭contrainte‬
C
‭PRIMARY‬‭KEY‬‭(‭c‬ olonne1‬‭,‬‭colonne2‬‭,‬‭.‬‭.‬‭.‬‭)‬

‭Cette syntaxe est là indispensable pour déclarer une clé primaire composite‬
‭(c’est-à-dire portant sur plusieurs colonnes).‬

‭Exemple 1 :‬

‭Create‬‭Table‬‭Client‬
‭(‬
‭CodeCl‬‭Varchar‬‭(‭6 ‬ ‬‭)‬‭Not‬‭Null,‬
‭Nom‬‭Varchar‬‭(‬‭40‬‭)‬‭Not‬‭Null,‬
‭Ville‬‭Varchar‬‭(‬‭40‬‭)‬

‭ ONSTRAINT‬‭Pk_Client‬
C
‭PRIMARY‬‭KEY‬‭(‭C
‬ odeCl‬‭)‬
‭)‬

‭Exemple 2 :‬

‭20‬‭/‬‭57‬
‭ REATE‬‭TABLE‬‭Detail‬
C
‭(‬
‭NumCom‬‭INT‬‭NOT‬‭NULL‬‭Foreign‬‭Key‬‭References‬‭Commande‬‭(‬‭NumCom‬‭),‬
‭CodeArt‬‭VARCHAR‬‭(‬‭6‬‭)‬‭NOT‬‭NULL‬‭Foreign‬‭Key‬‭References‬‭Article‬‭(‬‭CodeArt‬‭),‬
‭Qte‬‭INT‬

‭ ONSTRAINT‬‭Pk_Detail‬
C
‭PRIMARY‬‭KEY‬‭(‭N
‬ umCom‬‭,‭C
‬ odeArt‬‭)‬
‭)‬

‭Exemple 3 :‬

‭CREATE TABLE‬‭Emprunt‬
‭(‬
‭CodeA‬‭VARCHAR(6) Foreign Key References Adherent(CodeA),‬
‭CodeL‬‭VARCHAR(6) Foreign Key References Livre(CodeL),‬
‭DateEmp‬‭DateTime,‬
‭DateRetour DateTime‬

‭CONSTRAINT Pk_Emprunt‬
‭PRIMARY KEY (CodeA, CodeL, DateEmp)‬
‭)‬

‭V - 5 UNIQUE‬

‭On peut imposer à une colonne (ou plusieurs colonnes) de prendre des valeurs uniques‬
‭(c’est-à-dire sans doublons) même si ce n’est pas une clé primaire.‬

‭Exemples :‬

‭ALTER TABLE Client‬


‭ADD CONSTRAINT un_Nom‬
‭UNIQUE (Nom)‬

‭ALTER TABLE Client‬


‭ADD CONSTRAINT un_Nom_Prenom‬
‭UNIQUE (Nom,Prenom)‬

‭ALTER TABLE Client‬


‭ADD CONSTRAINT un_Nom_Ville‬
‭UNIQUE (Nom,Ville)‬

‭Remarque‬‭: la valeur NULL n’est autorisée qu’une seule‬‭fois dans une colonne UNIQUE.‬

‭V – 6 Clé étrangère‬

‭ es clés étrangères sont aussi des contraintes, et à nouveau, si on a oublié de les préciser‬
L
‭dès la création de la table, on peut les ajouter après. Attention : on ne peut faire de clé‬
‭étrangère que vers une clé primaire ou vers une colonne UNIQUE.‬

‭Exemple‬‭1 :‬

‭21‬‭/‬‭57‬
‭ reate‬‭Table‬‭Commande‬
C
‭(‬
‭NumCom‬‭Varchar‬‭(‬‭6‭)‬ ‬‭Primary‬‭Key‬‭,‬
‭DateCom‬‭Date‬‭Default‬‭GetDate‬‭(),‬
‭CodeCl‬‭Varchar‬‭(‭6
‬ ‬‭)‬
‭)‬

‭ LTER TABLE Commande‬


A
‭ADD CONSTRAINT Fk_CodeCl‬
‭FOREIGN KEY CodeCl REFERENCES Client(CodeCl)‬

‭Cette syntaxe est nécessaire si la clé étrangère est composite‬

‭ xemple 2‬‭: dans une base bibliothèque un emprunt‬‭concerne un exemplaire d’un livre, les‬
E
‭numéros ISBN et de copie doivent donc être les mêmes.‬

‭ LTER TABLE emprunts‬


A
‭ADD CONSTRAINT Fk_emprunts‬
‭FOREIGN KEY‬‭(isbn, no_copie)‬‭REFERENCES ouvrages‬‭(isbn,‬‭no_copie)‬

‭V – 7 Activer / Desactiver une Contrainte‬

‭ n ne peut désactiver que les contraintes de type‬‭clé étrangère ou‬


O
‭CHECK. Les contraintes de type‬‭Clé primaire, valeur‬‭par defaut et unique‬‭ne‬
‭peuvent pas être désactivées.‬

‭ LTER‬‭TABLE‬‭Client‬
A
‭ADD‬‭CONSTRAINT‬‭cst_Nom‬
‭CHECK‬‭(‭N
‬ om‬‭LIKE‬‭'A%'‬‭)‬

‭ elect‬‭*‬‭From‬‭Client‬
S
‭Insert‬‭into‬‭Client‬‭values‬‭(‭'‬Cl08'‬‭,‭'‬alami'‬‭,‭'‬Fès'‬‭)‬

‭Alter‬‭Table‬‭Client‬‭NOCHECK‬‭CONSTRAINT‬‭cst_Nom‬

‭Insert‬‭into‬‭Client‬‭values‬‭(‭'‬Cl09'‬‭,‭'‬Salami'‬‭,‭'‬Fès'‬‭)‬ ‭🡪‬ ‭Marche‬

‭Alter‬‭Table‬‭Client‬‭CHECK‬‭CONSTRAINT‬‭cst_Nom‬‭🡪‬ ‭Marche‬

‭On peut désactiver toutes les contraintes à la fois dans une table.‬

‭Alter‬‭Table‬‭Client‬‭NOCHECK‬‭CONSTRAINT‬‭ALL‬

‭Pour les réactiver, on fait le contraire :‬

‭Alter‬‭Table‬‭Client‬‭CHECK‬‭CONSTRAINT‬‭ALL‬

‬ bjects‬‭Where‬‭type‬‭=‬‭'F'‬ ‭🡪‬ ‭Afficher‬‭les foreign key.‬


‭Select‬‭*‬‭From‬‭sys‬‭.‭o

‬ bjects‬‭Where‬‭type‬‭=‬‭'Pk'‬ ‭🡪‬ ‭Afficher les primary key.‬


‭Select‬‭*‬‭From‬‭sys‬‭.‭o

‭22‬‭/‬‭57‬
‭VI - Sous-requêtes ( Subqueries)‬
‭Les conditions de sélection de la clause‬‭WHERE‬‭peuvent‬‭utiliser le résultat d’une autre‬
‭requête.‬

‭VI - 1 - Sous-requete renvoyant une valeur‬


‭ELECT‬‭
S NumCom, DateCom‬
FROM‬‭
‭ Commande‬
WHERE‬‭
‭ CodeCl‬‭
=‬‭
(‬‭
SELECT‬‭
CodeCl‬
FROM‬‭
‭ Client‬
WHERE‬‭
‭ Nom = 'Alami' )‬

‭VI - 2 - Sous-requete renvoyant une liste de valeurs‬


‭fficher les commandes des clients dont le nom commence par‬
A
‘A’ :‬

‭ELECT‬‭
S NumCom, DateCom‬
FROM‬‭
‭ Commande‬
WHERE‬‭
‭ CodeCl‬‭
IN‬‭
(‬‭
SELECT‬‭
CodeCl‬
FROM‬‭
‭ Client‬
WHERE‬‭
‭ Nom‬‭
LIKE‬‭
'A%' )‬

Afficher les clients qui n’ont pas de commande :‬


‭ELECT‬ ‭
S *‬
FROM‬‭
‭ Client‬
WHERE‬‭
‭ CodeCl‬‭
NOT‬‭
IN‬‭(‬‭
SELECT‬‭CodeCl‬
FROM‬‭
‭ Commande)‬

1.‬‭
‭ les articles dont le prix est superieur à tous les articles‬
dont Qdip = 100 :‬

‭ELECT‬‭
S CodeArt, Desi‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ PU‬‭
>‬‭
ALL‬‭
(‬‭
SELECT‬‭
PU‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ Qdisp = 100 )‬

‭ceci est equivalent à :‬

SELECT‬‭
‭ CodeArt, Desi‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ PU‬‭
>‬‭
(‬‭
SELECT Max(‬
PU‬
‭ )‬

FROM‬‭
‭ Article‬
WHERE‬‭
‭ Qdisp = 100 )‬

2.‬‭
‭ Les articles dont le prix est superieur à l'un des articles‬
dont Qdip = 100 :‬

‭23‬‭/‬‭57‬
SELECT‬‭
‭ CodeArt, Desi‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ PU‬‭
> ANY‬‭
(‬‭
SELECT‬‭
PU‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ Qdisp = 100 )‬

‭ceci est equivalent à :‬

‭ELECT‬‭
S CodeArt, Desi‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ PU‬‭
>‬‭
(‬‭
SELECT‬‭
Min(‬
PU‬
‭ )‬

FROM‬‭
‭ Article‬
WHERE‬‭
‭ Qdisp = 100 )‬

3.‬‭
‭ Tous les articles mais seulement s’il existe un dont Qdip =‬
100 :‬

SELECT‬‭
‭ CodeArt, Desi‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ EXISTS‬‭
(‬‭
SELECT‬‭CodeArt‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ Qdisp = 100 )‬

4.‬‭
‭ Tous les articles mais seulement s’il n'existe pas d'article‬
dont Qdip = 100 :‬

‭ELECT‬‭
S CodeArt, Desi‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ NOT EXISTS‬‭
(‬‭
SELECT‬‭CodeArt‬
FROM‬‭
‭ Article‬
WHERE‬‭
‭ Qdisp = 100 )‬

Prenons le cas des clients qui n’ont pas de commande :‬


‭ELECT‬ ‭
S *‬
FROM‬‭
‭ Client a‬
WHERE‬‭
‭ NOT‬‭Exists‬‭
(‬‭
SELECT‬‭CodeCl‬
FROM‬‭
‭ Commande‬
WHERE‬‭
‭ CodeCl = a.CodeCl)‬

‭Exercices‬‭:‬
‭17- Selectionner les livres qui ne sont jamais empruntés‬

‭ elect‬ ‭*‬
S
‭From‬ ‭Livre‬
‭Where‬ ‭CodeL‬‭Not‬‭In‬‭(‬‭Select‬‭Distinct‬‭CodeL‬‭From‬‭Emprunt‬‭)‬

‭24‬‭/‬‭57‬
‭En utilisant la fonction EXISTS :‬

‭ elect‬ ‭*‬
S
‭From‬ ‭Livre a‬
‭Where‬ ‭Not‬‭Exists‬‭(‬‭Select‬‭Distinct‬‭CodeL‬‭From‬‭Emprunt‬‭Where‬ ‭CodeL = a.CodeL‬‭)‬

‭18- Selectionner les Thèmes qui ne sont jamais empruntés‬

‭ elect‬‭*‬
S
‭From‬‭Thème‬‭a‬
‭Where‬‭CodeTh‬‭Not‬‭In‬‭(‬‭Select‬‭CodeTh‬
‭From‬‭Emprunt‬‭b‬
‭Join‬‭Livre‬‭c‬‭On‬‭b‬‭.‭C
‬ odeL‬‭=‬‭c‬‭.‬‭CodeL‬
‭Where‬‭CodeTh‬‭=‬‭a‬‭.‭C ‬ odeTh‬‭)‬

‭Insert‬‭Into‬‭Livre‬‭Values‬‭(‭'‬L05'‬‭,‭'‬Intro SQL'‬‭,‭'‬Alami'‬‭,‭5
‬ 0‬‭,‭'‬Th04'‬‭)‬

‭Etude de cas 1‬
‭Relation reflexive‬

‭25‬‭/‬‭57‬
‭I - Relation réflexive ( 0,1 à 0,n)‬
‭1.‬ ‭MCD‬

‭PersonneP‬ ‭PersonneE‬
‭ odeP‬
C ‭ odeP‬
C
‭Nom‬ ‭Nom‬
‭Prenom‬ ‭Prenom‬

‭Personne‬
‭ odeP‬
C
‭Père‬ ‭Nom‬

‭0,n‬ ‭Prenom‬

‭ nfant‬
E
‭0,1‬

‭2.‬ ‭MLD‬
‭MLD 1‬

‭PersonneP‬ ‭PersonneE‬

‭ odeP‬
C ‭ odeP‬
C
‭Nom‬ ‭Nom‬
‭Prenom‬ ‭Prenom‬
‭#CodeP‬

‭ ans ce Modèle on peut remarquer qu’il y a redondance (Répétition d’informations).‬


D
‭CodeP, Nom et Prenom se retrouve dans les deux tables. Par conséquent, on supprimera la‬
‭table‬‭PersonneP‬‭.‬
‭On remplacera CodeP par CodeE (Code Enfant).‬
‭On remplacera aussi #CodeP par CodeP (Code Père).‬
‭On obtiendra le modèle 2.‬

‭MLD 2‬‭(Modèle choisi)‬

‭Personne‬
‭ odeE‬
C
‭Nom‬
‭Prenom‬
‭CodeP‬

‭26‬‭/‬‭57‬
‭On veut tester ce modèle choisi pour s’assurer qu’il répondra à toutes nos réquêtes :‬

‭ odeE‬
C ‭ odeP‬
C
‭1‬ ‭‬
X ‭‬
A ‭2‬
‭2‬ ‭X‬ ‭B‬ ‭4‬
‭3‬ ‭X‬ ‭C‬ ‭2‬
‭4‬ ‭X‬ ‭D‬ ‭Null‬
‭5‬ ‭Y‬ ‭E‬ ‭Null‬

‭Create‬‭Database‬‭Personne‬

‭Use‬‭Personne‬

‭Create‬‭Table‬‭Personne‬
‭(‬
‭CodeE‬‭int‬‭Primary‬‭Key‬‭,‬
‭Nom‬‭VarChar‬‭(‭3‬ 0‬‭),‬
‭Prenom‬‭VarChar‬‭(‭3 ‬ 0‬‭),‬
‭CodeP‬‭int‬‭References‬‭Personne‬
‭)‬

I‭nsert‬‭Into‬‭Personne‬‭Values‬‭(‭1 ‬ ‬‭,‭'‬X'‬‭,‬‭'A'‬‭,‭2
‬ ‬‭)‬
‭Insert‬‭Into‬‭Personne‬‭Values‬‭(‭2 ‬ ‬‭,‭'‬X'‬‭,‬‭'B'‬‭,‭4
‬ ‬‭)‬
‭Insert‬‭Into‬‭Personne‬‭Values‬‭(‭3 ‬ ‬‭,‭'‬X'‬‭,‬‭'C'‬‭,‭2
‬ ‬‭)‬
‭Insert‬‭Into‬‭Personne‬‭Values‬‭(‭4‬ ‬‭,‭'‬X'‬‭,‬‭'D'‬‭,Null)‬
‭Insert‬‭Into‬‭Personne‬‭Values‬‭(‭5
‬ ‬‭,‭'‬Y'‬‭,‬‭'E'‬‭,Null)‬
‭Select‬‭*‬‭From‬‭Personne‬

‭1.‬ ‭Selection des personnes Père uniquement (dans la BD):‬

‭Select CodeE, Nom From Personne Where CodeP Is Null And‬


‭CodeE In (Select CodeP From Personne)‬

‭2.‬ ‭Selection des personnes Enfant uniquement (dans la BD):‬

Select‬‭
‭ *‬
‭rom‬‭
F Personne‬
Where‬ ‭
‭ CodeP‬‭
Is‬‭Not‬‭
Null‬‭And‬
CodeE‬‭
‭ Not‬‭In‬‭
(‭
S‬elect‬‭CodeP‬‭
From‬‭
Personne‬‭
Where‬ ‭
CodeP‬‭
Is‬‭
Not‬‭
Null)‬

Select‬‭
‭ *‬‭
From‬‭
Personne‬‭
Where‬‭
1‬‭
Is‬‭
Not‬‭
Null (1 <> Null‬‭
ne marche pas)‬

‭3.‬ ‭Selection des personnes Pére et Enfant (dans la BD):‬

‭Select CodeE, Nom From Personne‬


‭ here CodeP Is Not Null And CodeE In (Select CodeP From Personne)‬
W

‭27‬‭/‬‭57‬
‭4.‬ ‭Selection des personnes ayant des petits fils :‬

‭Select CodeE, Nom From Personne‬


‭ here CodeE In (Select CodeP From Personne‬
W
‭Where CodeE In (Select CodeP From Personne ))‬

‭-- Autre solution avec Join :‬

‭ elect‬‭Distinct‬‭a‬‭.‭C
S ‬ odeE‬‭,‬‭a‬‭.‭N
‬ om‬‭,‬‭a‭.‬‬‭Prenom‬
‭From‬‭Personne‬‭a‬
‭Join‬‭Personne‬‭b‬‭On‬‭a‬‭.‭C‬ odeE‬‭=‬‭b‬‭.‭C ‬ odeP‬
‭Join‬‭Personne‬‭c‬‭On‬‭b‬‭.‭C
‬ odeE‬‭=‬‭c‬‭.‭C ‬ odeP‬

‭5.‬ ‭Selection des personnes ayant un grand Père (dans la BD):‬

‭Select CodeE, Nom From Personne‬


‭ here CodeP In (Select CodeE From Personne‬
W
‭Where CodeP In (Select CodeE From Personne ))‬

‭-- Autre solution avec Join‬

‭ elect‬‭c‬‭.‬‭CodeE‬‭,‬‭c‬‭.‭N
S ‬ om‬‭,‬‭c‬‭.‬‭Prenom‬
‭From‬‭Personne‬‭a‬
‭Join‬‭Personne‬‭b‬‭On‬‭a‬‭.‭C ‬ odeE‬‭=‬‭b‬‭.‭C‬ odeP‬
‭Join‬‭Personne‬‭c‬‭On‬‭b‬‭.‭C ‬ odeE‬‭=‬‭c‬‭.‭C ‬ odeP‬

‭II - Relation réflexive ( 0,n à 0,n)‬


‭1.‬ ‭MCD‬
‭Personne‬
‭ odeP‬
C
‭Père‬ ‭Nom‬

‭0,n‬ ‭Prenom‬

‭ nfant‬
E
‭0,n‬

‭2.‬ ‭MLD‬
‭28‬‭/‬‭57‬
‭Personne‬ ‭PersonneE‬
‭ odeE‬
C ‭ ‬‭CodeE‬
#
‭Nom‬ ‭#‬‭CodeP‬
‭Prenom‬

-‭ -----------------------------------------------‬
‭--- Cas Relation reflexive plusieurs à plusieurs‬
‭-------------------------------------------------‬
‭Create‬‭Database‬‭Parenté‬

‭Use‬‭Parenté‬

‭Create‬‭Table‬‭Personne‬
‭(‬
‭CodeE‬‭int‬‭Primary‬‭Key‬‭,‬
‭Nom‬‭VarChar‬‭(‭3
‬ 0‬‭),‬
‭Prenom‬‭VarChar‬‭(‭3 ‬ 0‬‭)‬
‭)‬

I‭nsert‬‭Into‬‭Personne‬‭Values‬‭(‭1 ‬ ‬‭,‭'‬X'‬‭,‬‭'A'‬‭)‬
‭Insert‬‭Into‬‭Personne‬‭Values‬‭(‭2 ‬ ‬‭,‭'‬X'‬‭,‬‭'B'‬‭)‬
‭Insert‬‭Into‬‭Personne‬‭Values‬‭(‭3 ‬ ‬‭,‭'‬X'‬‭,‬‭'C'‬‭)‬
‭Insert‬‭Into‬‭Personne‬‭Values‬‭(‭4‬ ‬‭,‭'‬X'‬‭,‬‭'D'‬‭)‬
‭Insert‬‭Into‬‭Personne‬‭Values‬‭(‭5
‬ ‬‭,‭'‬Y'‬‭,‬‭'E'‬‭)‬
‭Select‬‭*‬‭From‬‭Personne‬

‭Create‬‭Table‬‭Parent‬
‭(‬
‭CodeE‬‭int‬‭References‬‭Personne‬‭,‬
‭CodeP‬‭int‬‭References‬‭Personne‬

‭ onstraint‬‭Pk_Parent‬
C
‭Primary‬‭Key‬‭(‬‭CodeE‬‭,‬‭CodeP‬‭)‬
‭)‬

I‭nsert‬‭Into‬‭Parent‬‭Values‬‭(‭1 ‬ ‬‭,‭2
‬ ‬‭)‬
‭Insert‬‭Into‬‭Parent‬‭Values‬‭(‭2‬ ‬‭,‭4
‬ ‬‭)‬
‭Insert‬‭Into‬‭Parent‬‭Values‬‭(‭3
‬ ‬‭,‭2
‬ ‬‭)‬

‭Delete‬‭Parent‬

-‭ - 1-‬
‭Select‬‭*‬‭From‬‭Personne‬
‭Where‬‭CodeE‬‭In‬‭(‬‭Select‬‭CodeP‬‭From‬‭Parent‬‭)‬
‭And‬‭CodeE‬‭Not‬‭In‬‭(‬‭Select‬‭CodeE‬‭From‬‭Parent‬‭)‬

-‭ - 2-‬
‭Select‬‭*‬‭From‬‭Personne‬
‭Where‬‭CodeE‬‭Not‬‭In‬‭(‬‭Select‬‭CodeP‬‭From‬‭Parent‬‭)‬
‭And‬‭CodeE‬‭In‬‭(‬‭Select‬‭CodeE‬‭From‬‭Parent‬‭)‬
‭29‬‭/‬‭57‬
-‭ - 3-‬
‭Select‬‭*‬‭From‬‭Personne‬
‭Where‬‭CodeE‬‭In‬‭(‬‭Select‬‭CodeP‬‭From‬‭Parent‬‭)‬
‭And‬‭CodeE‬‭In‬‭(‬‭Select‬‭CodeE‬‭From‬‭Parent‬‭)‬

-‭ - 4-‬
‭Select‬‭*‬‭From‬‭Personne‬
‭Where‬‭CodeE‬‭In‬‭(‬‭Select‬‭CodeP‬‭From‬‭Parent‬
‭Where‬‭CodeE‬‭In‬‭(‬‭Select‬‭CodeP‬‭From‬
‭Parent‬‭))‬

-‭ - 5-‬
‭Select‬‭*‬‭From‬‭Personne‬
‭Where‬‭CodeE‬‭In‬‭(‬‭Select‬‭CodeE‬‭From‬‭Parent‬
‭Where‬‭CodeE‬‭In‬‭(‬‭Select‬‭CodeP‬‭From‬
‭Parent‬‭))‬

‭30‬‭/‬‭57‬
‭Etude de cas 2‬
‭Heritage (Merise 2)‬

‭Héritage (Merise2) :‬

‭MCD :‬

‭MLD :‬

‭ alarié‬‭(‭M
S ‬ atricule‬‭, Nom, Prenom)‬
‭Commercial‬‭(#‬‭Matricule‬‭, ZoneGéo)‬
‭Technicien‬‭((#‬‭Matricule‬‭, Spécialité)‬

Create‬‭
‭ Database‬‭
Heritage‬

Use‬‭
‭ Heritage‬

‭reate‬‭
C Table‬‭
Salarié‬
(‬

Matricule‬‭
‭ int‬‭Primary‬‭
Key‬
,‬

Nom‬‭
‭ Varchar‬
(‬
‭ 30‬
‭ ),‬

Prenom‬‭
‭ Varchar‬(‭
‭3‬0‬
)‬

)‬

‭reate‬‭
C Table‬‭
Commercial‬
(‬

Matricule‬‭
‭ int‬‭
Primary‬‭
Key‬‭
References‬‭
Salarié‬
,‬

ZoneGéo‬‭
‭ Varchar‬
(‬
‭ 40‬
‭ )‬

)‬

‭reate‬‭
C Table‬‭
Technicien‬
(‬

Matricule‬‭
‭ int‬‭
Primary‬‭ Key‬‭
References‬‭
Salarié‬
,‬

Spécialité‬‭
‭ Varchar‬
(‭
‭4‬0‬
),‬

‭31‬‭/‬‭57‬
)‬

‭---‬
-
Insert‬‭
‭ Into‬‭
Salarié‬‭
Values‬‭
(‭
1
‬‬,‭
‭'‬A'‬
,‭
‭'‬X'‬
)‬

Insert‬‭
‭ Into‬‭
Salarié‬‭
Values‬‭
(‭
2
‬‬,‭
‭'‬B'‬
,‭
‭'‬Y'‬
)‬

Insert‬‭
‭ Into‬‭
Salarié‬‭
Values‬‭
(‭
3
‬‬,‭
‭'‬C'‬
,‭
‭'‬Z'‬
)‬

Insert‬‭
‭ Into‬‭
Salarié‬‭
Values‬‭
(‭
4
‬‬,‭
‭'‬D'‬
,‭
‭'‬W'‬
)‬

Insert‬‭
‭ Into‬‭
Salarié‬‭
Values‬‭
(‭
5
‬‬,‭
‭'‬E'‬
,‭
‭'‬T'‬
)‬

Select‬‭
‭ *‬‭
From‬‭
Salarié‬

‭nsert‬‭
I Into‬‭
Commercial‬‭
Values‬‭
(‬1‭
‭,‬‬
'Fès Ouest'‬
‭ )‬

Insert‬‭
‭ Into‬‭
Commercial‬‭
Values‬‭
(‬2‭
‭,‬‬
'Fès Est'‬
‭ )‬

Insert‬‭
‭ Into‬‭
Commercial‬‭
Values‬‭
(‬5‭
‭,‬‬
'Fès Milieu'‬
‭ )‬

‭nsert‬‭
I Into‬‭
Technicien‬‭
Values‬‭
(‬3‭
‭,‬‬
'Developpeur'‬
‭ )‬

Insert‬‭
‭ Into‬‭
Technicien‬‭
Values‬‭
(‬4‭
‭,‬‬
'Reseaux'‬
‭ )‬

Insert‬‭
‭ Into‬‭
Technicien‬‭
Values‬‭
(‬5‭
‭,‬‬
'Gestion'‬
‭ )‬

1-‬‭
‭ Afficher toutes les infos des commerciaux‬

‭elect‬‭
S a‭
.
‬‬Matricule‬
‭ ,‬‭
‭ Nom‬ ,‬‭
‭ Prenom‬
,‬‭
‭ ZoneGéo‬
From‬‭
‭ Salarié‬‭a‬
Join‬‭
‭ Commercial‬‭b‬‭
On‬‭a‭
.
‬‬Matricule‬‭
‭ =‬‭
b‭
.‬‬
Matricule‬

2-‬‭
‭ Afficher toutes les infos des techniciens‬

‭elect‬‭
S a‭
.
‬‬Matricule‬
‭ ,‬‭
‭ Nom‬ ,‬‭
‭ Prenom‬
,‬‭
‭ Spécialité‬
From‬‭
‭ Salarié‬‭a‬
Join‬‭
‭ Technicien‬‭b‬‭
On‬‭a‭
.
‬‬Matricule‬‭
‭ =‬‭
b‭
.‬‬
Matricule‬

3-‬‭
‭ Afficher les commerciaux et les techniciens avec toutes les infos.‬

‭elect‬‭
S 'Commercial'‬‭As‬‭ TypeS‬
,‬
‭ a‭
‭.
‬‬Matricule‬
‭ ,‬‭
‭ Nom‬,‬‭
‭ Prenom‬
,‬‭
‭ ZoneGéo‬‭
As‬
InfoSpéciales‬

From‬‭
‭ Salarié‬‭
a‬
Join‬‭
‭ Commercial‬‭
b‬‭
On‬‭ a‭
.‬‬
Matricule‬‭
‭ =‬‭
b‭
.‬‬
Matricule‬

UNION‬

Select‬‭
‭ 'Technicien'‬,‭
‭a‬‬
.‭
‭M‬atricule‬ ,‬‭
‭ Nom‬
,‬‭
‭ Prenom‬
,‬‭
‭ Spécialité‬
From‬‭
‭ Salarié‬‭
a‬
Join‬‭
‭ Technicien‬‭
b‬‭
On‬‭ a‭
.‬‬
Matricule‬‭
‭ =‬‭
b‭
.‬‬
Matricule‬

4-‬‭
‭ Afficher les salariés ayant le même nom.‬

‭elect‬‭
S a‭
.
‬‬Matricule‬
‭ ,‬
‭ a‭
‭.‬‬
Prenom‬
‭ ,‭
‭b‬‬
.‭
‭M‬atricule‬ ,‭
‭b
‬‬.‭
‭P‬renom‬
From‬‭
‭ Salarié‬‭a‬
Join‬‭
‭ Salarié‬‭b‬‭
On‬‭
a‬.‭
‭N‬om‬‭
=‬‭
b‬.‭
‭N‬om‬‭And‬‭
a‬.‭
‭M
‬atricule‬‭ >‬‭
b‬.‭
‭M‬atricule‬

5-‬‭
‭ Afficher les salariés commerciaux et techniciens en même temps.‬
‭32‬‭/‬‭57‬
‭ elect‬‭a‬‭.‭M
S ‬ atricule‬‭,‬‭Nom‬‭,‬‭Prenom‬
‭From‬‭Salarié‬‭a‬
‭Join‬‭Commercial‬‭b‬‭On‬‭a‬‭.‭M ‬ atricule‬‭=‬‭b‭.‬‬‭Matricule‬
‭Join‬‭Technicien‬‭c‬‭On‬‭a‭.‬‬‭Matricule‬‭=‬‭c‬‭.‭M
‬ atricule‬

‭VII - UNION (ALL) – INTERSECT - EXCEPT :‬

‭1.‬ ‭A U B‬
SELECT‬‭
‭ CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'A%'‬
UNION‬

SELECT‬‭
‭ CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'%D'‬

‭2.‬ ‭A U B (UNION ALL)‬


SELECT‬‭
‭ CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'A%'‬
UNION ALL‬

SELECT‬‭
‭ CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'%D'‬

Remarque :‬
‭ ‭ NION donne le résultat sans doublon.‬
U
‭UNION ALL donne le résultat avec doublon.‬

‭3.‬ ‭A ∩ B‬
SELECT‬‭
‭ CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'A%'‬
INTERSECT‬

SELECT‬‭
‭ CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'%D'‬

‭4.‬ ‭A \ B‬

‭ELECT‬‭
S CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'A%'‬
EXCEPT‬

SELECT‬‭
‭ CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'%D'‬

‭5.‬ ‭B \ A‬

‭ELECT‬‭
S CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'%D'‬
EXCEPT‬

SELECT‬‭
‭ CodeCl‬
,‬‭
‭ Nom‬‭
FROM‬‭
Client‬‭
Where‬‭
Nom‬‭
Like‬‭
'A%'‬

‭33‬‭/‬‭57‬
‭VIII - Indexes :‬

‭Un index sert à accélérer la recherche.‬

‭1.‬ C‭ REATE INDEX‬‭Index1‬


‭ON‬‭Client (Nom)‬

‭ ette instruction SQL crée un index nommé‬‭Index1‬‭selon‬‭la colonne‬‭Nom‬


C
‭dans la table‬‭Client‬‭.‬

‭Select * From Client Where Nom = ‘Alami’‬

‭2.‬ C‭ REATE UNIQUE INDEX Index2‬


‭ON Client (Nom)‬

‭Cette instruction SQL crée un index unique dans la table‬‭Client‬‭. C.à.d. sans doublons.‬

‭3.‬ C‭ REATE INDEX Index3‬


‭ON Client (Nom, Ville)‬

‭C’est un index selon une combinaison de deux colonnes.‬

Select‬‭
‭ *‬‭
From‬‭
Client‬‭
Where‬‭
Nom‬‭
=‬‭
'Alami'‬‭
And‬‭
Ville‬‭
=‬‭
'Fès'‬

‭DROP INDEX Client.Index1‬

‭IX - SELECT INTO :‬

‭Make a Backup Copy‬‭- Now we want to make an exact‬‭copy of the data in our‬
‭"Client" table.‬

‭ ELECT *‬
S
‭INTO Client_Backup‬
‭FROM Client‬

‭We can also use the IN clause to copy the table into another database:‬

‭ELECT‬ ‭
S *‬
INTO‬‭
‭ DB1‬
.‬
‭ dbo‬
‭ .‬
‭ Client‬

FROM‬‭
‭ Client‬

Copie de la table Client de la BD Vente à la BD DB1‬


‭We can also copy only a few fields into the new table:‬

‭34‬‭/‬‭57‬
‭ ELECT Nom, Ville‬
S
‭INTO Client_Backup‬
‭FROM Client‬

‭We can also add a WHERE clause.‬

‭ ELECT Nom, Ville‬


S
‭INTO Client_Backup‬
‭FROM Client‬
‭WHERE Ville = 'Fès'‬

‭Selecting data from more than one table is also possible.‬

‭ ELECT a.Nom, b.NumCom‬


S
‭INTO Commande_Backup‬
‭FROM Client a‬
‭INNER JOIN Commande b‬
‭ON a.CodeCl = b.CodeCl‬

‭XI -‬‭Requêtes multi-bases.‬

‭Pour accéder à une table on utilise la syntaxe générale suivante :‬

‭Nom_Du_Serveur . Nom_De_LaBase . Nom_Du_Propriétaire . Nom_De_LaTable‬

‭Le Propriétaire est généralement‬‭dbo‬‭(database owner).‬

‭1.‬ ‭Des BDs dans le même serveur.‬

‭Exemple 1 :‬

‭Soient 4 bases de données BD1,BD2,BD3 et BD4 dans un même serveur SERV1.‬

‭SERV1‬
‭ ase de données‬
B ‭Tables‬
‭BD1‬ ‭🡪‬ ‭Client‬
‭BD2‬ ‭🡪‬ ‭Commande‬
‭BD3‬ ‭🡪‬ ‭Detail‬
‭BD4‬ ‭🡪‬ ‭Article‬

‭ P (Code SQL) :‬
T
-- Création des BDs : BD1, BD2, BD3 et BD4‬

‭reate‬‭
C Database‬‭
BD1‬
Create‬‭
‭ Database‬‭
BD2‬
Create‬‭
‭ Database‬‭
BD3‬
Create‬‭
‭ Database‬‭
BD4‬

-- Création de la table Client dans BD1‬



Use‬‭
‭ BD1‬
‭35‬‭/‬‭57‬
Create‬‭
‭ Table‬‭
Client‬‭
(. . .)‬

Insert‬‭
‭ into‬‭
Client‬‭
values‬ ‭
. . .‬

-- Création de la table Commande dans BD2‬



Use‬‭
‭ BD2‬

Create‬‭
‭ Table‬‭Commande‬‭ (‬
. . .‬
‭ ,‬

CodeCl‬‭
‭ Varchar‬
(‬
‭ 6‭
‭)‬‬ ‭-- Sans Foreign key‬
)‬

‭et‬‭
s dateFormat‬‭
dmy‬
Insert‬‭
‭ into‬‭
Commande‬‭
values‬‭
. . .‬

-- Création de la table Detail dans BD3‬



Use‬‭
‭ BD3‬

Create‬‭
‭ Table‬‭Detail‬‭(‬
NumCom‬‭
‭ Varchar‬(‭
‭6‬‬
),‬‭
‭ -- Sans Foreign key references,‬
CodeArt‬‭
‭ Varchar‬
(‬
‭ 6‭
‭)‬,‬‭
-- Sans Foreign key references,‬
. . .‬‭
‭ )‬

Insert‬‭
‭ into‬‭
Detail‬‭
. . .‬

-- Création de la table Article dans BD4‬



Use‬‭
‭ BD4‬

Create‬‭
‭ Table‬‭
Article‬‭
(‭
.
‬ . .‬
)‬

Insert‬‭
‭ into‬‭
Article‬‭
values‬ ‭
. . .‬

-- Nous voulons faire des sélections en se plaçant dans BD1:‬



Use‬‭
‭ BD1‬

‭elect‬‭
S *‬‭
From‬‭
Client‬
Select‬‭
‭ *‬‭
From‬‭
BD2‬
.‭
‭d‬bo‬
.‭
‭C‬ommande‬
Select‬‭
‭ *‬‭
From‬‭
BD3‬
.‭
‭d‬bo‬
.‭
‭D‬etail‬
Select‬‭
‭ *‬‭
From‬‭
BD4‬
.‭
‭d‬bo‬
.‭
‭A‬rticle‬

-- Nous voulons calculer le CA d’un Client :‬


‭elect‬‭
S a‭
.
‬‬CodeCl‬
‭ ,‬‭
‭ Sum‬
(‬
‭ c‭
‭.
‬‬PU‬
‭ *‭
‭b‬‬
.‭
‭Q‬te‬)‬‭
‭ As‬‭
CA‬
From‬‭
‭ BD2‬.‬
‭ dbo‬
‭ .‬
‭ Commande‬‭
‭ a‬
Join‬ ‭
‭ BD3‬.‬
‭ dbo‬
‭ .‬
‭ Detail‬‭
‭ b‬‭On‬‭a‭
.‬‬
NumCom‬‭
‭ =‬‭
b‬.‭
‭N‬umCom‬
Join‬ ‭
‭ BD4‬.‬
‭ dbo‬
‭ .‬
‭ Article‬‭
‭ c‬‭
On‬‭b‬.‭
‭C‬odeArt‬‭
=‬‭c‬.‭
‭C‬odeArt‬
Group‬‭
‭ By‬‭ a‭
.‬‬
CodeCl‬

-- Total de chaque commande :‬


‭36‬‭/‬‭57‬
‭elect‬‭
S a‭
.
‬‬NumCom‬
‭ ,‬‭
‭ Sum‬
(‬
‭ c‭
‭.
‬‬PU‬
‭ *‭
‭b‬‬
.‭
‭Q‬te‬)‬‭
‭ As‬‭
Total‬
From‬‭
‭ BD2‬.‬
‭ dbo‬
‭ .‬
‭ Commande‬‭
‭ a‬
Join‬ ‭
‭ BD3‬.‬
‭ dbo‬
‭ .‬
‭ Detail‬‭
‭ b‬‭On‬‭a‭
.‬‬
NumCom‬‭
‭ =‬‭
b‬.‭
‭N‬umCom‬
Join‬ ‭
‭ BD4‬.‬
‭ dbo‬
‭ .‬
‭ Article‬‭
‭ c‬‭
On‬‭b‬.‭
‭C‬odeArt‬‭
=‬‭c‬.‭
‭C‬odeArt‬
Group‬‭
‭ By‬‭ a‭
.‬‬
NumCom‬

‭2.‬ ‭Trois BDs dans trois serveurs différents.‬

‭SERV1‬ ‭SERV2‬ ‭SERV3‬


‭BD1‬‭🡪‬‭Commande‬ ‭BD2‬‭🡪‬‭Detail‬ ‭BD3‬‭🡪‬‭Article‬
‭Et Client‬

‭Exemple 1 :‬

‭ elect CodeCl, Sum(PU*Qte) As CA‬


S
‭From‬‭SERV1.‬‭DB1.dbo.Commande a‬
‭Join‬ ‭SERV2.‬‭DB2.dbo.Detail b On a.NumCom = b. NumCom‬
‭Join‬ ‭SERV3.‬‭DB3.dbo.Article c On b.CodeArt = c.CodeArt‬
‭Group By CodeCl‬

‭Exemple 2 :‬

‭ elect a.NumCom, b.Desi‬


S
‭From Entreprise1.GestionCommerciale.dbo.Commande a‬
‭Join Entreprise2.GestionProduction.dbo.Article b On a.CodeArt = b.CodeArt‬

‭XII - Les Vues :‬


‭ efinition‬‭: Une Vue est un objet SQL contenant‬‭le résultat d’une requête Select et‬
D
‭qui ressemble à une table.‬

‭XII – 1‬ ‭Création d’une vue :‬

‭Exemple 1 : Une vue contenant les clients de Fès‬

‭Create‬‭View‬‭Vue_ClientDeFes‬
‭As‬
‭Select * From Client Where Ville = 'Fes'‬

‭Select * From Vue_ClientDeFes‬

‭On peut changer les noms des colonnes dans la vue :‬

‭o‬
G
Alter‬‭
‭ View‬‭
Vue_ClientDeFes‬
(‬
‭ C‭
‭,‬‬
N‭
‭,‬‬
V‭
‭)‬‬
‭37‬‭/‬‭57‬
‭s‬
A
Select‬‭
‭ *‬‭
From‬‭
Client‬‭
Where‬‭
Ville‬‭
=‬‭
'Fes'‬
Go‬

Select‬ ‭
‭ *‬ ‭
From‬‭
Vue_ClientDeFes‬


‭ ‬‭
Modifier une vue :‬
Alter‬‭
‭ View‬‭Vue_ClientDeFes‬
(‬
‭ col1‬
‭ ,‬‭
‭ col2‬
,‬‭
‭ col3‬
)‬

As‬

Nouvelle requête‬‭
‭ Select‬‭
. . .‬

✔‬ ‭
‭ Renommer une vue :‬

Exec‬‭
‭ sp_rename‬‭
'Vue_ClientsDeFès'‬
,‭
‭'
‬Vue1'‬

‭Exemple 2 : Une vue contenant les noms des clients et le nombre de leurs‬
‭commandes.‬

‭Create‬‭View‬‭Vue_NbCmdClient‬
‭As‬
‭Select Nom, COUNT(NumCom) As NbCommandes‬
‭From Client a‬
‭Join Commande b On a.CodeCl = b.CodeCl‬
‭Group By Nom‬

‭Select * From Vue_NbCmdClient‬

‭Exemple 3 :‬ ‭Cas Biblio – Une vue contenant chaque livre emprunté avec sa date‬
‭d’emprunt et sa date de retour.‬

‭use Biblio‬

‭ reate‬‭View‬‭Vue_EmpruntRetour‬
C
‭As‬
‭Select Titre, DateEmp, DateRetour‬
‭From Livre a‬
‭Join Emprunt b On a.CodeL = b.CodeL‬

‭ elect * From Vue_EmpruntRetour‬


S
‭Select * From Emprunt‬

‭Exemple 4 :‬‭Même exemple avec cette fois-ci calcul‬‭du retard par rapport à 15 jours.‬

‭Create‬‭View‬‭Vue_EmpRetard‬
‭As‬
‭Select Titre, DateEmp, DateRetour, DATEDIFF(day,DateEmp,DateRetour) - 15‬
‭As Retard‬
‭From Livre a‬
‭Join Emprunt b On a.CodeL = b.CodeL‬
‭Where Retard > 0‬

‭38‬‭/‬‭57‬
‭ elect * From Vue_EmpRetard Order By Retard Desc‬
S
‭Select * From Emprunt‬

‭Select DATEDIFF(day,'10/9/2014','20/9/2014')‬

‭XII – 2‬ ‭Insertion dans une vue :‬

‭Toute modification dans la table client sera faite aussi au niveau de la vue.‬

‭INSERT INTO Client Values ('Cl05','eee','Fes')‬

‭Select * From Vue_ClientDeFes‬

‭ e même, toute modification au niveau de la vue sera faite au niveau de la table.‬


D
‭Sauf si une donnée ne vérifie pas la condition de filtrage (Where) de la vue. Dans ce‬
‭cas, la ligne sera insérée dans la table d’origine et non pas dans la vue.‬

‭INSERT INTO Vue_ClientDeFes Value('Cl14','ttt','Mohammadia')‬

‭Select * From Client‬

‭XII – 3‬ ‭Modification d’une vue :‬

‭use Vente‬

‭Alter‬‭View‬‭Vue_ClientDeFes‬
‭As‬
‭Select * From Client Where Ville = 'Fes' And Nom Like 'A%'‬

‭Select * From Vue_ClientDeFes‬

‭INSERT INTO Client VALUES('Cl05','Alami','Fes')‬

‭Select * From Vue_ClientDeFes‬

‭XII– 4‬ ‭Suppression d’une vue :‬

‭Drop‬‭View‬ ‭Vue_ClientDeFes‬

‭39‬‭/‬‭57‬
‭XIII - Les Transactions‬
‭ efinition‬‭:‬
D
‭Une Transaction est une suite d’instructions SQL qui réussissent ou échouent en totalité‬
‭(pas de réussite partielle).‬
‭Si elle réussit, la base de données est modifiée, et la transaction est inscrite au journal.‬
‭Si une instruction échoue, toute la transaction est annulée et la base de données n’est pas‬
‭modifiée.‬

‭Exemple‬‭:‬

‭1.‬ ‭Pas de transaction :‬


‭ pdate Client . . .‬
U
‭Delete Client . . .‬ ‭🡨‬‭Echec‬
‭Update Client . . .‬

‭Si Delete ne réussit pas les deux Update peuvent réussir.‬

‭2.‬ ‭Avec transaction :‬


‭Begin Tran‬
‭Update Client . . .‬
‭Delete Client . . .‬ ‭🡨‬‭Echec‬ ‭Echec‬
‭Update Client . . .‬
‭Commit Tran‬

‭Si, maintenant, Delete ne réussit pas les deux Update sont annulés.‬

‭Exemple‬‭: Paiement par carte guichet (carte bancaire).‬

‭Super Marché‬

‭🡨‬ ‭ arte‬
C ‭🡨‬ ‭Montant achats‬
‭🡨‬‭Lecteur‬

‭Agence client‬ ‭Agence Super Marché‬

‭ pdate CompteClient‬
U ‭ pdate CompteSP‬
U
‭Set Solde = Solde – Montant‬ ‭Set Solde = Solde + Montant‬
‭Where NumCompteClient = ‘XXXX’‬ ‭Where NumCompteSP = ‘YYYY’‬

‭40‬‭/‬‭57‬
‭ ommentaire‬‭:‬
C
‭Si l’instruction Update déduisant le montant des achats du solde du compte client‬
‭réussit, alors que l’instruction Update ajoutant le montant des achats au solde du compte du‬
‭Super Marché échoue, l’argent est perdu. De là, la nécessité de mettre les deux Update dans‬
‭une transaction. Dans ce cas, le Update réussissant sera annulé et l’argent sera remis au‬
‭compte client.‬

‭Exemple pratique :‬

‭Use‬‭Vente‬

‭Select‬‭*‬‭From‬‭Client‬

-‭ - Pas de transaction‬
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭2 ‬ 0‬‭,‭'‬yyy'‬‭,‬‭'Fès'‬‭)‬
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭2‬ 1‬‭,‭'‬zzz'‬‭,‬‭'Fès'‬‭)‬
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭2
‬ 2‬‭,‭'‬www'‬‭,‭'‬Fès'‬‭)‬

-‭ - Prise en charge des transactions par SQL Server‬


‭SET XACT_ABORT ON‬

-‭ - Prise en charge des transactions par l’utilisateur (Try … Catch)‬


‭SET XACT_ABORT OFF‬

‭ egin‬‭Tran‬
B
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭'‬Cl21'‬‭,‭'‬zzz'‬‭,‬‭'Fès'‬‭)‬
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭'‬Cl22'‬‭,‭'‬www'‬‭,‭'‬Fès'‬‭)‬
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭'‬Cl20'‬‭,‭'‬yyy'‬‭,‬‭'Fès'‬‭)‬
‭Commit‬‭Tran‬

‭ elete‬‭Client‬‭Where‬‭CodeCl‬‭In‬‭(‭'‬Cl21'‬‭,‭'‬Cl22'‬‭)‬
D
‭Select‬‭*‬‭From‬ ‭Client‬

‭-- Transaction à l'aide de Try Catch‬

‭ egin‬‭Try‬‭;‬
B
‭Begin‬‭Tran‬
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭'‬Cl21'‬‭,‭'‬zzz'‬‭,‬‭'Fès'‬‭)‬
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭'‬Cl22'‬‭,‭'‬www'‬‭,‭'‬Fès'‬‭)‬
‭Insert‬‭into‬‭Client‬‭Values‬‭(‭'‬Cl20'‬‭,‭'‬yyy'‬‭,‬‭'Fès'‬‭)‬
‭Commit‬‭Tran‬
‭End‬‭Try‬
‭Begin‬‭Catch‬‭;‬
‭RollBack‬‭Transaction‬‭;‬
‭Raiserror‬‭(‭'‬Transaction annulée !!'‬‭,‭1 ‬ 6‬‭,‭1 ‬ ‬‭);‬
‭Return‬‭;‬
‭End‬‭Catch‬‭;‬

‭41‬‭/‬‭57‬
‭XII - LES JOINTURES EXTERNES :‬
‭LEFT JOIN – RIGHT JOIN – FULL JOIN.‬
‭Soient les deux tables Client et Commande de la base de données‬‭Vente‬‭:‬

‭Commençons par une jointure interne :‬

‭elect‬‭
S Nom‬
,‬‭
‭ NumCom‬
,‬‭
‭ DateCom‬
From‬‭
‭ Client‬‭
a‬
Join‬‭
‭ Commande‬‭
b‬‭
On‬‭a‭
.
‬‬CodeCl‬‭
‭ =‬‭
b‬.‭
‭C‬odeCl‬

‭Resultat :‬

‭ euls les clients ayant à des commandes sont affichés, et seules les commandes ayant‬
S
‭des clients sont affichées. On dit que‬‭la jointure‬‭est obligatoire à gauche et à droite‬‭.‬

‭ ne jointure externe consiste à rendre la jointure non obligatoire à gauche, ou bien à droite ou‬
U
‭bien les deux.‬

‭1.‬ ‭Jointure externe gauche :‬


‭elect‬‭
S Nom‬
,‬‭
‭ NumCom‬
,‬‭
‭ DateCom‬
From‬‭
‭ Client‬‭
a‬
LEFT‬‭
‭ Join‬‭
Commande‬‭b‬‭
On‬‭
a‬.‭
‭C
‬odeCl‬‭
=‬‭
b‭
.‬‬
CodeCl‬

(Ou LEFT‬‭
‭ OUTER Join)‬

‭Resultat :‬

‭42‬‭/‬‭57‬
‭Tous les clients sont affichés, même ceux n’ont pas de commandes. Alors que, seules‬
l‭es commandes ayant des clients sont affichées. La jointure est devenue facultative à gauche.‬
‭On dit qu’il s’agit d’‬‭une jointure externe gauche‬‭. ‬

‭2.‬ ‭Jointure externe droite :‬


‭elect‬‭
S Nom‬
,‬‭
‭ NumCom‬
,‬‭
‭ DateCom‬
From‬‭
‭ Client‬‭ a‬
RIGHT‬‭
‭ Join‬‭ Commande‬‭
b‬‭
On‬‭
a‭
.
‬‬CodeCl‬‭
‭ =‬‭
b‬.‭
‭C‬odeCl‬
(Ou RIGHT‬‭
‭ OUTER Join)‬

‭Resultat :‬

‭Seuls les clients ayant des commandes sont affichés. Alors que, toutes les commandes‬
s‭ ont affichées, même celles n’ayant pas de client. La jointure est devenue facultative à droite.‬
‭On dit qu’il s’agit d’‬‭une jointure externe droite‬‭. ‬

‭3.‬ ‭Jointure externe à gauche et à droite (externe totale) :‬


‭elect‬‭
S Nom‬ ,‬‭
‭ NumCom‬,‬‭
‭ DateCom‬
From‬‭
‭ Client‬‭ a‬
FULL‬‭
‭ Join‬‭ Commande‬‭ b‬‭
On‬‭
a‬.‭
‭C
‬odeCl‬‭
=‬‭
b‭
.‬‬
CodeCl‬

FULL‬‭
‭(ou‬‭ OUTER‬‭Join)‬
‭Resultat :‬

‭43‬‭/‬‭57‬
‭Tous les clients sont affichés, même ceux n’ayant pas à des commandes. Et toutes les‬
c‭ ommandes sont affichées, même celles n’ayant pas de clients. Les jointures de gauche et de‬
‭droite sont devenues facultatives. On dit qu’il s’agit d’‬‭une jointure externe pleine(ou totale)‬‭. ‬

‭Serie D’exercices‬
‭ xercice I :‬
E
‭Soit le modèle relationnel suivant relatif à la gestion des notes annuelles d'une promotion‬
‭d'étudiants :‬

‭ TUDIANT (NEtudiant, Nom, Prénom)‬


E
‭MATIERE (CodeMat, LibelléMat, CoeffMat)‬
‭EVALUER (NEtudiant, CodeMat, Date, Note)‬

‭Question :‬

‭ ) Créer la base de données avec les clés primaire et étrangère.‬


1
‭2) Ajouter la colonne date de naissance dans Etudiant : DateN.‬
‭3) Ajouter la colonne Groupe : Groupe not null.‬
‭4) Ajouter la contrainte unique pour les deux attributs (NEtudiant, CodeMat).‬
‭5) Ajouter une colonne Age calculé automatiquement à partir de DateN.‬
‭6) Ajouter une contrainte, valeur entre 0 et 20 pour la note.‬
‭7) Créer une vue qui affiche la liste des étudiants (Groupe, Nom, Prénom) et leur moyenne‬
‭Général‬

‭Exercice II :‬

‭Soit le modèle relationnel suivant :‬

‭ MPLOYEE (Matr, NomE, Poste, DateEmb, Salaire, NumDept)‬


E
‭DEPT (NumDept, NomDept, Lieu)‬
‭PROJET (CodeP, NomP)‬
‭PARTICIPATION (Matr, CodeP, Fonction)‬

‭Question :‬

‭44‬‭/‬‭57‬
‭ ) Ajouter un attribut Commission dans Employée.‬
1
‭2) Ajouter un attribut JourPrévu dans Projet (Nombre de jour prévu dans ce projet)‬
‭3) Ajouter un attribut JourRéalisé dans Participation (Nombre de jour réalisé par l’employée‬
‭dans le projet)‬
‭4) Ajouter des contraintes d’intégrité de domaine sur les deux champs JourPrévu et‬
‭JourRéalisé strictement positif.‬
‭5) Effectué une augmentation de 10% des salaires des employées du département « finance‬
‭».‬
‭6) Créer un index sur l’attribut NomE pour optimiser la recherche par nom.‬
‭7) Créer une vues sur la table Employée pour afficher Matr, NomE, Poste, NomDept et un‬
‭champ calculé salaire avec commission.‬
‭8) Créer une vues Projet pour afficher NomP, JourPrévu et le pourcentage des JourRéalisé par‬
‭rapport au JourPrévu‬

‭Sécurité des bases de données‬

‭45‬‭/‬‭57‬
‭Gestion des utilisateurs, des groupes‬
‭et des rôles dans SQL Server 2017‬

‭I - Gestion des accès serveur‬


‭ vant de pouvoir commencer à travailler avec les données de nos bases, il est impératif‬
A
‭de se connecter au serveur SQL. Cette étape permet de s’identifier au niveau du serveur SQL,‬
‭afin de pouvoir exploiter les droits qui ont étés attribués à notre connexion.‬
‭Dans SQL Server, il existe deux modes d’authentification :‬

‭1 - Mode d'authentification Windows.‬

‭46‬‭/‬‭57‬
‭Les utilisateurs sont authentifiés par Windows et reçoivent l'accès à SQL Server par‬
l‭'intermédiaire d'une connexion mappée à leur compte Windows (ou à un groupe Windows‬
‭dont ils sont membres).‬

‭●‬ ‭Creation d'une connection Windows‬


‭reate‬‭
C Login‬‭
[Rachid-PC\Rachid]‬
From‬‭
‭ Windows‬
With‬‭
‭ Default_Database‬‭
= Vente‬

Ou dans le cas d’un domaine :‬


‭reate‬‭
C Login‬‭
[NomDuDomaine\Khalid]‬
From‬‭
‭ Windows‬
With‬‭
‭ Default_Database‬‭
= Vente‬

‭2 – Configuration du mode d'authentification SQL Server et Windows.‬

‭ es utilisateurs peuvent se connecter à SQL Server en fournissant un nom de‬


L
‭connexion et un mot de passe corrects, validés par SQL Server indépendamment de‬
‭Windows. Ce mode est appelé aussi‬‭mode mixte‬‭.‬

‭ omment passer du mode d’authentification Windows au mode d’authentification‬


C
‭Mixte(SQLServer et Windows) :‬

‭Pour que cette modification soit effective,il faut redemarrer le serveur SQL.‬

‭Definitions et rôles des comptes de connexion et des comptes utilisateurs :‬

‭47‬‭/‬‭57‬
‭●‬ ‭Creation d'une connection SQL‬

‭reate‬‭
C Login‬‭
Con1‬
With‬‭
‭ PassWord‬‭= '123',‬
Default_Database‬‭
‭ = Vente‬

‭reate‬‭
C Login‬‭
Con2‬
With‬‭
‭ PassWord‬‭= '123',‬
Default_Database‬‭
‭ = Vente‬

‭Remarque :‬‭On ne pas se connecter avec ses comptes‬‭de connexion avant‬


‭d'avoir créé des comptes utilisateurs.‬

‭3 – Desactiver une connection‬


ALTER‬‭
‭ LOGIN‬‭
Con1‬‭
DISABLE‬

‭4 – Activer une connection‬


ALTER‬‭
‭ LOGIN‬‭
Con1‬‭
ENABLE‬

‭5 – Changer le mot de passe‬


ALTER‬‭
‭ LOGIN‬‭
Con1‬‭
WITH‬‭
PASSWORD‬‭
= '1234'‬

‭6 – changer le nom de la connection‬


ALTER‬‭
‭ LOGIN‬‭
Con1‬‭
WITH‬‭
NAME‬‭
= Con‬
‭48‬‭/‬‭57‬
‭7 – Suppression d'une connection SQL‬
‭rop‬‭
D Login‬‭
Con1‬
Drop‬‭
‭ Login‬‭
Con2‬

‭II - Gestion des utilisateurs de base de données‬


‭1 – Création des utilisateurs de base de données‬
Use‬‭
‭ Vente‬

‭reate‬‭
C User‬‭
Ali‬
For‬‭
‭ Login‬‭
Con1‬
With‬‭
‭ Default_Schema‬‭
= dbo‬
Go‬

‭reate‬‭
C User‬‭
Ahmed‬
For‬‭
‭ Login‬‭
Con2‬
With‬‭
‭ Default_Schema‬‭
= monschema‬
Go‬

Remarques‬
‭ ‭:‬

‭ ‬ M ‭ aintenant, il est possible de se connecter au serveur avec Con1 et Con2.‬
‭✔‬ ‭Un login (Compte de connexion) ne peut être lié qu’à un seul compte utilisateur dans la‬
‭même base données.‬
‭✔‬ ‭Un login peut être lié à plusieurs comptes utilisateurs, mais dans des bases données‬
‭différentes..‬

‭2 – Modification d’un utilisateur‬


‭lter‬‭
A User‬‭
AncienNom‬
With‬‭
‭ Name‬‭= nouveauNom,‬
Default_Schema‬‭
‭ = nouveauSchema‬

‭3 – Suppression d’utilisateurs de base de données‬


‭rop‬‭
D User‬‭
Ali‬
Drop‬‭
‭ User‬‭
Ahmed‬

‭ – Octroi et enlèvement d’autorisations à des utilisateurs de base de‬


4
‭Données (GRANT / DENY / REVOKE)‬
‭RANT SELECT‬‭
G ON‬‭
Client‬‭
TO‬
GRANT‬‭
‭ SELECT‬‭
ON‬‭
Article‬‭
TO‬‭
Ahmed‬

‭RANT SELECT ON‬‭


G Client‬‭
TO‬‭
Ali‬‭
WITH GRANT OPTION‬
Ali peut donc executer :‬

Select * From Client‬

Il peut aussi executer :‬

GRANT SELECT ON‬‭
‭ Client‬‭
TO‬‭
Ahmed‬
‭49‬‭/‬‭57‬
‭RANT‬‭
G SELECT‬
(CodeCl,Nom)‬‭
‭ ON‬‭
Client‬‭
TO‬‭
Ali‬
GRANT‬‭
‭ UPDATE‬
(PU),INSERT‬‭
‭ ON‬‭
Article‬‭
TO‬‭
Ahmed‬

‭EVOKE‬‭
R SELECT‬‭
ON‬‭
Client‬‭
FROM‬‭
Ali CASCADE‬
REVOKE‬‭
‭ SELECT‬‭
ON‬‭
Article‬‭
FROM‬‭Ahmed‬

‭ENY‬‭
D SELECT‬‭
ON‬‭
Client‬‭TO‬‭
Ali‬‭
CASCADE‬
DENY‬‭
‭ SELECT‬‭
ON‬‭
Article‬‭
TO‬‭Ahmed‬‭
CASCADE‬

‭●‬ E
‭mprunter l'identité d'un utilisateur pour tester les‬
autorisations‬

‭XECUTE AS USER‬‭
E = 'Ali'‬
EXECUTE AS USER‬‭
‭ = 'Ahmed'‬

‭●‬ ‭
Revenir au contexte de sécurité par défaut (l’Admin)‬

REVERT‬

‭🡺‬‭Différences entre DENY, REVOKE‬


‭ n privilège (autorisation) peut être accordé (GRANT) ou bien retiré (‬‭REVOKE‬‭) s'il a‬
U
‭été accordé. L'instruction ‭D ‬ ENY‬‭permet d'interdire‬‭l'utilisation d'un privilège particulier‬
‭même si le privilège en question a été accordé soit directement, soit par l'intermédiaire‬
‭d'un rôle.‬

‭GRANT : autoriser‬
‭rant‬‭
G Select‬‭
On‬‭
Client‬‭
To‬‭
Ali‬
Grant‬‭
‭ Select,Update,Delete‬‭On‬‭
Client‬‭
To‬‭
Ali‬

‭Vérifier graphiquement les changements‬

‭REVOKE : enlever (retirer) le ou les autorisation(s).‬

‭evoke‬‭
R Select‬‭On‬‭
Client‬‭ From‬‭Ali‬
‭Annuler l’autorisation à Ali de faire un Select‬ ‭sur la table Client.‬
Revoke‬‭
‭ Select,Update,Delete‬‭ On‬‭
Client‬‭ From‬‭Ali‬
‭Annuler l’autorisation à Ali de faire un Select, Update et Delete sur la table‬
‭Client.‬

‭Vérifier graphiquement les changements‬

‭DENY : interdire (refuser) une ou plusieurs autorisation(s).‬


DENY‬‭
‭ SELECT‬‭
ON‬‭
Client‬‭
TO‬‭
Ali‬

‭Vérifier graphiquement les changements‬

‭50‬‭/‬‭57‬
‭5 – Création de rôles‬

‭Un rôle est un groupe d’utilisateurs.‬


‭Exemple 1‬‭:‬
‭6.‬ ‭Creation Role Commercial‬
CREATE‬‭
‭ ROLE‬‭
Commercial‬

‭7.‬ ‭Ajout d’utilisateurs au rôle commercial :‬

Syntaxe‬
‭ :‬

‭‬
Alter Role [RoleName] add member [MemberName];‬

‭- Création d'un role‬


-
Create‬‭
‭ Role‬‭
Commercial‬

‭- Ajout de membres (Users) au role‬


-
Alter‬‭
‭ Role‬‭
Commercial‬‭
Add‬‭
Member Ali‬
Alter‬‭
‭ Role‬‭
Commercial‬‭
Add‬‭
Member Ahmed‬

‭- Ou bien‬
-
EXEC‬‭
‭ sp_addrolemember‬‭
Commercial‬
,‬‭
‭ Ali‬
EXEC‬‭
‭ sp_addrolemember‬‭
Commercial‬
,‬‭
‭ Ahmed‬

-- Pour retirer(supprimer) un utilisateur d’un rôle :‬


EXEC‬‭
‭ sp_droprolemember‬‭
Commercial‬
,‬‭
‭ Ali‬

Avant d'être supprimé, il doit être vidé.‬


‭8.‬ ‭Ajout d’autorisation au role commercial‬

‭RANT‬‭
G SELECT(Nom,Ville),Update(Ville),Insert‬‭
ON‬‭
Client‬‭
TO‬‭
commercial‬
GRANT‬‭
‭ SELECT(Desi,PU),Update(Qdisp)‬‭
ON‬‭
Article‬‭
TO‬‭
commercial‬

‭Exemple 2‬‭:‬

‭51‬‭/‬‭57‬
‭ 1, U2 sont deux secrétaires.‬
U
‭U3, U4, U5, U6 sont quatre commerciaux.‬
‭U7 est un magasinier.‬

‭9.‬ ‭Creation des rôles Secrétaire, Commercial et Magasinier :‬

ROLE‬‭Secrétaire‬
‭REATE‬‭
C
ROLE‬‭Commercial‬
CREATE‬‭

ROLE‬‭Magasinier‬
CREATE‬‭

10.‬ ‭
‭ Ajout des utilisateurs aux rôles :‬

‭lter Role‬‭Secrétaire‬ ‭
A Add Member‬‭
U1‬
Alter Role‬S‭ecrétaire‬ ‭
‭ Add Member‬‭
U2‬

‭lter
A Role‬‭Commercial‬ ‭
Add Member‬‭
U3‬
Alter
‭ Role‬‭Commercial‬ ‭
Add Member‬‭
U4‬
Alter
‭ Role‬‭Commercial‬ ‭
Add Member‬‭
U5‬
Alter
‭ Role‬‭Commercial‬ ‭
Add Member‬‭
U6‬

Alter Role‬‭Magasinier‬ ‭
‭ Add Member‬‭
U7‬

11.‬ ‭
‭ Ajout d’autorisations aux roles‬

GRANT‬‭
‭ SELECT ON‬‭
Client,Article‬‭
TO‬‭
Secrétaire‬

‭RANT‬‭
G SELECT ON‬‭
Client, Article‬‭
TO‬‭
Commercial‬
GRANT‬‭
‭ INSERT ON‬‭
Client‬‭
TO‬‭
Commercial‬
GRANT‬‭
‭ INSERT ON‬‭
Commande, Detail‬‭
TO‬‭
Commercial‬

GRANT‬‭
‭ ALL ON‬‭
Article‬‭
TO‬‭
Magasinier‬

‭12.‬ ‭Supprimer un rôle :‬

‭- Pour retirer(supprimer) un utilisateur d’un rôle :‬


-
EXEC‬‭
‭ sp_droprolemember‬‭
Commercial‬
,‬‭
‭ Ali‬
EXEC‬‭
‭ sp_droprolemember‬‭
Commercial‬
,‬‭
‭ Ahmed‬

‭- Supprimer le role Commercial‬


-
Drop‬‭
‭ Role‬‭
Commercial‬
-- ou bien‬

Exec‬‭
‭ sp_droprole‬‭
Commercial‬

‭Remarque :‬‭un rôle ne peut être supprimé que lorsqu’il‬‭est vide‬

‭6 – Création d’un schéma‬


‭Un schéma est un ensemble logique d’objets à l’intérieur des bases de données sur le‬
s‭ erveur. Concrètement, les schémas permettent une gestion plus aisée des autorisations sur‬
‭des objets. Comme nous l’avons vu précédemment, un utilisateur est mappé sur un‬
‭schéma dès sa création, obligatoirement. Si toutefois, aucun nom de schéma n’est précisé,‬
‭alors l’utilisateur sera mappé sur dbo par défaut.‬

‭52‬‭/‬‭57‬
Syntaxe‬
‭ ‭:‬

‭REATE‬‭
C SCHEMA‬‭
schema1‬
AUTHORIZATION‬‭
‭ nomproprietaire‬
Options‬

Exemple:‬

‭o‬
G
Create‬‭
‭ Schema‬‭
schema1‬
Go‬

-- Creation d'objets dans le schema‬


‭reate‬‭
C Table‬‭schema1‬
.‬
‭ T1‬‭
‭ (‬IdT1‬‭
‭ int‬
)‬

Go‬

Create‬‭
‭ View‬‭
schema1‬.‭
‭V
‬ue1‬‭ As‬‭
Select‬‭
*‬‭
From‬‭
Client‬
Go‬

‭elect‬‭
S *‬‭
From‬‭
schema1‬
.‭
‭T‬1‬
Select‬‭
‭ *‬‭
From‬‭
schema1‬
.‭
‭V‬ue1‬

‭7 – Transfert d’objets entre schémas :‬


Syntaxe‬
‭ ‭:‬

‭ LTER‬ ‭SCHEMA‬ ‭S‬‭chemaDestination‬


A
‭TRANSFER‬ ‭S‬‭chemaSource‬‭.‭n
‬ omobjet‬

‭ chemaDestination‬‭: nom du schéma à modifier.‬


S
‭SchemaSource. Nomobjet‬‭:‬‭ce sont les divers objets‬‭à déplacer dans le‬
‭S‭c‬ hemaDestination‬‭.‬

‭Exemple 1‬‭: Transfert d'objet dans shema1‬

‭- Transfert d'objet de schema à schema‬


-
Create‬‭
‭ Table‬‭
T2‬‭
(‬IdT2‬‭
‭ int‬
)‬‭
‭ --> T2 est dans dbo‬

‭lter‬‭
A Schema‬‭schema1‬
Transfer‬‭
‭ dbo‬
.‬
‭ T2‬

Select‬‭
‭ *‬‭
From‬‭
schema1‬
.‭
‭T‬2‬

‭8 - Autorisations sur un schema‬

‭- 1- Octroi d'autorisations à Ali sur schema1‬


-
Grant‬‭
‭ Select‬
,‬
‭ Insert‬‭
‭ On‬‭
Schema‬‭
::‬‭
schema1‬‭
To‬‭
Ali‬

‭- 2- Utilisation des Schemas et des rôles‬


-
Grant‬‭
‭ Select‬
,‬
‭ Update‬‭
‭ On‬‭
Schema‬‭
::‬‭
schema1‬‭
To‬‭
Commercial‬

‭53‬‭/‬‭57‬
‭9 – Suppression d’un schéma‬
Syntaxe‬
‭ ‭:‬

‭DROP‬‭SCHEMA‬‭nomschema‬

‭Exemple :‬

‭- Suppression d'un schema‬


-
Drop‬‭
‭ Schema‬‭
schema1‬

‭- Vider schema1 = Transferer T1, T2 et Vue1 vers le schema dbo‬


-
Alter‬‭
‭ Schema‬‭
dbo‬ --> Schema destination‬

Transfer‬‭
‭ schema1‬
.‬
‭ T1‬
‭ --> Schema source‬

‭lter‬‭
A Schema‬‭
dbo‬
Transfer‬‭
‭ schema1‬
.‬
‭ T2‬

‭lter‬‭
A Schema‬‭
dbo‬
Transfer‬‭
‭ schema1‬
.‬
‭ Vue1‬

‭- Maintenant, on peut supprimer schema1‬


-
Drop‬‭
‭ Schema‬‭
schema1‬

‭Remarque :‬‭un schéma ne peut être supprimé que lorsqu’elle‬‭est vide‬‭.‬

GRANT‬‭
‭ SELECT,INSERT,UPDATE ON‬‭
DATABASE :: Vente To‬‭
Ali‬

‭Résumé de la partie Sécurité en SQL‬

‭●‬ ‭Création d’une connexion‬

‭ reate Login Con1‬


C
‭With PassWord = ‘123’‬
‭Default_Database = Vente‬

‭ reate Login Con2‬


C
‭With PassWord = ‘123’‬
‭Default_Database = Vente‬

‭54‬‭/‬‭57‬
‭●‬ ‭Création de deux utilisateurs‬
‭ reate User U1‬
C
‭For Login Con1‬
‭Default_Schema = dbo‬

‭ reate User U2‬


C
‭For Login Con2‬
‭Default_Schema = dbo‬

‭●‬ ‭Octroi d’autorisations à U1‬


‭ rant Select(Nom),Delete On Client To U1‬
G
‭Revoke Delete On Client From U1‬
‭Deny Update(Nom) On Client To U1‬

‭ ‬ ‭Création d’un schema‬



‭Create Schema schema1‬

‭🡺‬ ‭Création d’une table T1 dans schema1 :‬


‭Create Table schema1.T1 (IdT1 int)‬
‭🡺‬ ‭Création d’une table T2 dans dbo :‬
‭Create Table T2 (IdT2 int)‬
‭🡺‬ ‭Transfert d’une table T2 du schema dbo à schema1 :‬
‭Alter Schema schema1‬
‭Transfer dbo.T2‬
‭‬ N
● ‭ ous avons maintenant dans schema1 les deux tables T1 et T2.‬

‭ ‬ ‭Octroi d’autorisations à U1 :‬

‭Grant Insert,Update On Schema :: schma1 To U1‬

‭●‬ C
‭ réation d’un rôle.‬
‭Create Role role1‬

‭ ‬ ‭Ajout de membres (utilisateurs) à role1.‬



‭Alter Role role1 Add Member U1‬
‭Alter Role role1 Add Member U2‬

‭●‬ ‭Octroi d’autorisations à role1 :‬


‭Grant Select(Nom,Ville),Update On Client To role1‬

‭ ‬ ‭Octroi d’autorisations à role1 sur schema1:‬



‭Grant Select,Delete On Schema :: schema1 To role1‬

‭●‬ ‭Maintenant, U1 et U2 ont le droit de faire Seletct et Delete sur T1 et T2.‬

‭55‬‭/‬‭57‬
‭Exercice I :‬

‭Soit une base de données DB_Prod contenant 5 tables (T1, T2, T3, T4, T5),‬

‭‬
● ‭ e schéma TABLES_PROD contient les tables T1, T2, T3,‬
L
‭●‬ ‭Le Rôle Admin_PROD contient les utilisateurs U1, U2‬
‭●‬ ‭Le Rôle USER_PROD contient les utilisateurs U3, U4‬
‭●‬ ‭Le rôle ADMIN_PROD aura les droits : Insert, Update, Delete, Select …,sur le schéma‬
‭TABLES_PROD.‬
‭ ‬ ‭Seuls les utilisateurs membres d'USER_PROD pourront effectuer des requêtes sur les‬

‭tables.‬
‭●‬ ‭Faire des tests avec U1 et U3 pour voir.‬

‭Solution :‬

‭Create Schema TABLES_PROD‬

‭ lter Schema TABLES_PROD‬


A
‭Transfer dbo.T1‬
‭Alter Schema TABLES_PROD‬
‭Transfer dbo.T2‬
‭Alter Schema TABLES_PROD‬
‭Transfer dbo.T3‬

‭ reate Role Admin_PROD‬


C
‭Create Role USER_PROD‬

‭ lter Role Admin_PROD Add Member U1‬


A
‭Alter Role Admin_PROD Add Member U2‬

‭ lter Role USER_PROD Add Member U3‬


A
‭Alter Role USER_PROD Add Member U4‬

‭ rant All On Schema :: TABLES_PROD To Admin_PROD‬


G
‭Grant Select On Schema :: TABLES_PROD To USER_PROD‬
‭Grant Select On T4,T5 To USER_PROD‬

‭Fin du Cours‬

‭56‬‭/‬‭57‬
‭57‬‭/‬‭57‬

Vous aimerez peut-être aussi