Introduction au SQL Server 2008
Introduction au SQL Server 2008
L2 - INFORMATIQUE
Sommaire
1 Introduction ............................................................................................................................................................... 4
2 Pré-requis .................................................................................................................................................................. 5
2.1 Présentation ...................................................................................................................................................... 5
2.2 Les expressions .................................................................................................................................................. 5
2.3 Les opérateurs ................................................................................................................................................... 6
2.4 Les fonctions ...................................................................................................................................................... 7
3. Les instructions DDL .................................................................................................................................................... 12
3 13
4 Les instructions DML ............................................................................................................................................... 13
3.1 Présentation .................................................................................................................................................... 13
3.2 Création, modification et suppression de données ......................................................................................... 14
3.2.1 L’instruction INSERT ................................................................................................................................ 14
3.2.2 L’instruction UPDATE............................................................................................................................... 16
3.2.3 L’instruction DELETE ................................................................................................................................ 17
3.3 Lire et trier des données.................................................................................................................................. 18
3.3.1 L’instruction SELECT ................................................................................................................................ 18
3.3.2 Changer le nom des colonnes (ALIAS) ..................................................................................................... 18
3.3.3 La condition WHERE ................................................................................................................................ 19
3.3.4 Les projections de données ..................................................................................................................... 20
3.3.5 Les calculs simples ................................................................................................................................... 22
3.3.6 Le produit cartésien ................................................................................................................................. 22
3.3.7 Les jointures ............................................................................................................................................ 23
3.3.8 La close ORDER BY ................................................................................................................................... 25
3.3.9 L’opérateur UNION .................................................................................................................................. 26
3.3.10 L’opérateur EXCEPT ................................................................................................................................. 27
3.3.11 L’opérateur INTERSECT ............................................................................................................................ 27
3.3.12 La clause TOP ........................................................................................................................................... 28
3.3.13 Créer une table grâce à SELECT INTO ...................................................................................................... 28
3.3.14 La clause COMPUTE et COMPUTE BY ...................................................................................................... 29
3.3.15 Les opérateurs ROLLUP et CUBE.............................................................................................................. 30
3.3.16 L’opérateur OVER .................................................................................................................................... 31
3.3.17 L’opérateur NTILE .................................................................................................................................... 32
3.3.18 Les sous-requêtes .................................................................................................................................... 32
3.3.19 Les instructions PIVOT et UNPIVOT ......................................................................................................... 32
3.3.20 L’instruction MERGE ................................................................................................................................ 34
5 Le SQL Procédural .................................................................................................................................................... 35
4.1 Les variables .................................................................................................................................................... 35
4.1.1 Les variables utilisateur ........................................................................................................................... 35
4.1.2 Les variables système .............................................................................................................................. 35
4.2 Les transactions ............................................................................................................................................... 35
4.3 Les lots et les scripts ........................................................................................................................................ 36
4.4 Le contrôle de flux ........................................................................................................................................... 37
4.4.1 L’instruction RETURN............................................................................................................................... 37
4.4.2 L’instruction PRINT .................................................................................................................................. 37
4.4.3 L’instruction CASE .................................................................................................................................... 38
4.4.4 Les blocs BEGIN … END ............................................................................................................................ 38
4.5 La gestion des curseurs.................................................................................................................................... 40
4.6 Les exceptions ................................................................................................................................................. 43
4.6.1 Lever une exception ................................................................................................................................ 43
4.6.2 Gestion des erreurs dans le code ............................................................................................................ 44
6 Conclusion ............................................................................................................................................................... 45
1 Introduction
Dans ce cours, nous allons étudier les bases du langage Transact SQL. La version du langage
Transact SQL utilisée est celle de SQL Server 2008. Pour ce faire, nous allons définir les différentes
parties du langage (DML, DDL, DCL), puis détailler la partie DML, qui est celle qui sert à manipuler les
données de façon générale.
2 Pré-requis
Avant de lire ce cours, nous vous conseillons :
- D’avoir déjà utilisé l’interface d’administration de SQL Server 2008 : SQL Server Management
Studio (Chapitre 1).
- D’avoir les bases dans la construction d’un modèle relationnel de données (Chapitre 2).
- Les bases fondamentales du langage T-SQL
2.1 Présentation
Le T-SQL (Transact Structured Query Langage) est un langage de communication avec une base
de données relationnelle SQL Server. Il définit une batterie « simple » mais complète de toutes les
opérations exécutables sur une base de données (lecture de données, opérations d’administration du
serveur, ajout, suppression et mises à jour d’objets SQL - tables, vues, procédures stockées,
déclencheurs, types de données personnalisés … -). Ce langage est composé d’instructions, réparties
dans de 3 catégories distinctes :
• DML : Data Modification Language, soit langage de manipulation de données. Dans cette
catégorie, s’inscrivent les instructions telles que l’instruction SELECT ou encore lesinstructions
qui nous permettent la création, la mise à jour et la suppression de données stockées dans les
tables de la base de données. Il est important de retenir que le DML sert simplement pour les
données, et en aucun cas pour la création, mise à jour ou suppression d’objets dans la base de
données SQL Server.
• DDL : Data Definition Language, soit langage de définition de données. Les instructions de cette
catégorie, permettent d’administrer la base de données, ainsi que les objets qu’elle contient.
Elles ne permettent pas de travailler sur les données. Aussi, elles ne seront pas traitées dans
ce chapitre.
• DCL : Data Control Language, soit langage de contrôle d’accès. Cette catégorie d’instructions
nous permet de gérer les accès (autorisations) aux données, aux objets SQL, aux transactions
et aux configurations générales de la base.
Ces trois catégories combinées permettent que le langage T-SQL prenne en compte des
fonctionnalités algorithmiques, et admette la programmabilité. Le T-SQL est non seulement un langage
de requêtage, mais aussi un vrai langage de programmation à part entière. Sa capacité à écrire des
procédures stockées et des déclencheurs (Triggers), lui permet d’être utilisé dans un environnement
client de type .NET, au travers d’une application en C# ou en [Link]. Dans cechapitre, nous allons
détailler la partie DML du T-SQL exclusivement. Auparavant, nous étudierons différents éléments
syntaxiques qui composeront la syntaxe de ce langage, à savoir les expressions, les opérateurs et les
fonctions. Par la suite, nous traiterons l’aspect procédural (algorithmique) de ce langage.
- Les constantes : une constante est une variable, dont la valeur ne peut être changée lors de
l’exécution d’instructions T-SQL.
- Les noms de colonnes : ils pourront être utilisés comme expressions. La valeur de l’expression
étant la valeur stockée dans une colonne pour une ligne donnée.
- Les variables : il s’agit d’entités qui peuvent être employées en tant qu’expressions ou dans
des expressions. Les variables sont préfixées par le caractère @. Les variables systèmes sont
préfixées par les caractères @@. La valeur de l’expression variable est la valeur de la variable
elle-même.
- Les fonctions : il est possible d’utiliser comme expression n’importe quelle fonction. Elles
permettent d’exécuter des blocs d’instructions T-SQL, et de retourner une valeur.
- Les expressions booléennes : elles sont destinées à tester des conditions. Elles sont utilisées
dans des structures algorithmiques de type WHILE, IF ou encore dans la clause WHERE d’une
requête SQL, à affiner de permettre d’afficher une recherche, ou bien à poser une condition
d’exécution.
- Les sous-requêtes : une sous requête SELECT peu être placée en tant qu’expression. Lavaleur
de l’expression est la valeur renvoyée par la requête.
+ Addition
- Soustraction
* Multiplication
/ Division
% Modulo (reste de division)
& ET
| OU
^ OU exclusif
~ NON
= Égale
> Supérieur
>= Supérieur ou égal
< Inférieur
<= Inférieur ou égal
<> Différent
Exp1 IN (exp2, exp3, …) Compare l’expression seule à toutes les
expressions de la liste
IS NULL Renvoie True si l’expression est NULL. False le
cas échéant
Exp1 BETWEEN minimum AND maximum Recherche si la valeur de Exp1 est comprise
entre la valeur « minimum » et « maximum ».
Les bornes minimum et maximum sont incluses
EXISTS (Sous Requête) Renvoie True, si et seulement si la sous requête
renvoie au moins une ligne
Exp1 LIKE Permet de filtrer des données suivant un
modèle
_ Un caractère quelconque
% N caractères quelconques
*ab…+ Un caractère dans la liste ab…
[a-z] Un caractère dans l’intervalle a-z
*^ab…+ Un caractère en dehors de la liste ou de
l’intervalle spécifié
ab… Le ou les caractères eux-mêmes
PI () Valeur de PI.
DEGREES (exp1) Conversion d’exp1 de radian vers degrés.
RADIANS (exp1) Conversion d’exp1 de degrés vers radians.
SIN (exp1), COS (exp1), TAN (exp1), COT (exp1) Sin, cos ou tangente d’exp1.
ACOS (exp1), ASIN (exp1), ATAN (exp1) Arc cos, arc sin ou arc tan d’exp1.
ATN2 (exp1, exp2) Angle dont la tangente se trouve dans
l’intervalle exp1 et exp2.
Type À partir de À
bigint -[Link].854.775.808 [Link].854.775.807
int -2147483648 2147483647
smallint -32768 32767
tinyint 0 255
bit 0 1
Decimal -10 ^ 38 1 10 ^ 38 -1
numeric -10 ^ 38 1 10 ^ 38 -1
money -922,337,203,685,477.5808 +922,337,203,685,477.5807
smallmoney -214,748.3648 +214,748.3647
Numerics approximatif
Type À partir de À
float 1,79 E + 308- 1,79 E + 308
reel -3.40E + 38 3.40E + 38
datetime et smalldatetime
Type À partir de À
datetime (3,33 exactitude millisecondes) 1 janvier 1753 31 déc 9999
smalldatetime (précision de 1 minute) 1 janvier 1900 6 juin 2079
Chaînes de caractères
Type Description
De longueur fixe de caractères Unicode avec une longueur maximum de
char
8000 caractères.
varchar Texte unicode de longueur variable allant jusqu’à 2 Go.
text Texte non unicode de longueur maximale 2Go
Les chaînes de caractères Unicode
Type Description
la longueur de données Unicode-fixe avec une longueur maximale de 4000
nchar
caractères.
la longueur de données Unicode et variable, avec une longueur maximum
nvarchar
de 4000 caractères.
nvarchar longueur Unicode données variables avec une longueur maximale de
(max) 230 caractères (SQL Server 2005 uniquement).
la longueur de données Unicode et variable, avec une longueur maximale
ntext
de 1073741823 caractères.
Binary Cordes
Type Description
De longueur fixe des données binaires d'une longueur maximale de 8000
binaire
octets.
De longueur variable des données binaires d'une longueur maximale de
varbinary
8000 octets.
varbinary De longueur variable des données binaires d'une longueur maximale de
(max) 231 octets (SQL Server 2005 uniquement).
De longueur variable des données binaires d'une longueur maximale de
image
2147483647 octets.
Pour créer une base de données qui sera appelé “ma_base” il suffit d’utiliser la requête suivante qui est très
simple:
CREATE TABLE Nom_table (colonne1 Type_champ1, colonne2 Type_champ2, colonne3 Type_champ3 ...);
3
4 Les instructions DML
3.1 Présentation
Pour toutes les instructions du DML, il existe dans SQL Server un outil simple pour retrouver
la syntaxe voulue rapidement (Pour des instructions simples, telle le SELECT, UPDATE…). La démarche
est simple. Via le menu contextuel d’une table, sélectionnez « Générer un script de la table en tant
que… ». Il nous est alors proposé de sélectionner l’action que nous voulons accomplir : SELECT, INSERT,
UPDATE ou DELETE. Cette action peut aussi être réalisée sur d’autres objets SQL de la base de
données.
3.2 Création, modification et suppression de données
3.2.1 L’instruction INSERT
L’instruction INSERT, comme son nom l’indique, va nous permettre d’ajouter une ligne de
données dans une table de la base de données. Le code générique, d’ajout d’une ligne de données
est la suivante :
Dans ce code générique, nous demandons à SQL Server d’ajouter un enregistrement à la table
Client, appartenant au schéma dbo dans la base de données Entreprise. Pour préciser les colonnes
pour lesquelles nous allons ajouter des données, il est nécessaire de préciser le nom des colonnes,
après l’instruction INSERT INTO. Le mot clé VALUES nous permet de fournir des valeurs aux champs.
Il est impératif que les valeurs soient dans le même ordre que celui des colonnes, tout d’abord pour la
cohérence des données, mais aussi pour respecter la compatibilité des données avec le type que vous
avez assigné à votre table au moment de sa création. Dans le cas où certaines de vos colonnes
acceptent des valeurs NULL, il existe deux méthodes pour obtenir cette valeur. La première, est
d’omettre le nom de la colonne et la valeur correspondante dans l’instruction. La seconde vise à laisser
la colonne dans la description, mais à préciser le mot clé NULL dans la clause VALUES. Pourdes
chaines de caractères, il faut placer celles-ci entre simples cotes. Dans le cas d’un champ de type
identité (possédant une incrémentation automatique grâce à la contrainte IDENTITY), il n’est pas
nécessaire de spécifier ni le nom du champ, ni sa valeur.
Après avoir exécuté le code ci-dessus, le message suivant apparait, confirmant de sa bonne
exécution :
Dans le cas d’une insertion multiple d’enregistrements, la syntaxe sera la même, à l’exception
près qu’au lieu d’une seule série de données après le mot clé VALUES, vous en spécifier lenombre
voulu. Si nous voulons ajouter deux enregistrements dans une même instruction Insert, alorsla syntaxe
est la suivante :
Le message suivant s’affiche, après l’exécution de cette instruction, ce qui confirme bien que
l’enregistrement multiple a été exécuté sans erreur :
Enfin, il est possible d’ajouter des enregistrements à l’aide de l’instruction SELECT, qui va copier
les enregistrements d’une table (source) vers une autre table (destination). Voici un exemple :
INSERT Commande
SELECT Id_Client, GETDATE(), Id_Stock, 1
FROM Client, Stock
WHERE Id_Client = 3
AND Id_Stock = 5
Dans ce cas, nous allons ajouter dans la table commande, les informations sélectionnées. Ici,
Id_Client, la date du jour grâce à la fonction GETDATE(), Id_Stock, et le chiffre 1 qui correspond à
la quantité que nous voulons ajouter à la commande de notre client. Les informations concernant
Id_Client et Id_Stock seront sélectionnées en fonction des conditions précisées après la clause WHERE.
Grâce à ce lot, nous allons ajouter la troisième ligne présente dans le résultat présenté ci- dessous.
UPDATE [Entreprise].[dbo].[Client]
SET [Nom_Client] = <Nom_Client, varchar(50),>
,[Prenom_Client] = <Prenom_Client, varchar(50),>
,[Numero_Client] = <Numero_Client, varchar(20),>
,[Adresse_Client] = <Adresse_Client, varchar(50),>
,[Mail_Client] = <Mail_Client, varchar(50),>
WHERE <Conditions de recherche,,>
GO
L’instruction ci-dessus permet de mettre à jour la table Client de la base de données Entreprise.
La clause SET permet d’indiquer les champs à mettre à jour. La clause WHERE, sert à cibler les
enregistrements à mettre à jour. Voici l’enregistrement de la table Client dont le champ Id-Client vaut
3:
Voici une instruction SQL permettant de modifier le nom de ce client :
UPDATE [Entreprise].[dbo].[Client]
SET [Adresse_Client] = ‘18 Rue du cotton’
WHERE Id_Client = 3
GO
Il est aussi possible d’effectuer des opérations grâce à un UPDATE. Par exemple, on peut
augmenter les prix des articles d’un magasin de 10%, en multipliant le prix de tous les articles par 1,1.
Après avoir exécuté le code, on remarque que le client dont l’identifiant est 4, n’existe plus :
La suppression multiple de données est possible, par exemple si dans notre cas, nous avions
précisé une plage d’identifiants dans notre clause WHERE.
3.3 Lire et trier des données
3.3.1 L’instruction SELECT
L’instruction SELECT permet de sélectionner des données (tout ou partied’enregistrements),
d’une ou plusieurs tables. Elle offre aussi la possibilité de les trier, et de les regrouper. La syntaxe
générale de cette instruction est la suivante :
SELECT [Id_Client]
,[Nom_Client]
,[Prenom_Client]
,[Numero_Client]
,[Adresse_Client]
,[Mail_Client]
FROM [Entreprise].[dbo].[Client]
GO
Voici une instruction SELECT permettant de lire le nom et l’adresse Email de tous les clients
(si notre but avait été de sélectionner toutes les colonnes, au lieu de lister toutes celles-ci, il est possible
d’indiquer que nous les sélectionnons toutes avec le simple caractère « * ») :
SELECT [Nom_Client]
,[Mail_Client]
FROM [Entreprise].[dbo].[Client]
GO
Cette instruction SELECT sélectionne tous les champs de tous les enregistrements pour
lesquels la colonne Id_Client est égale soit à 1, 2, 3 et 6. On remarque alors que dans notre code, nous
avons utilisé la condition WHERE, une colonne, un opérateur de comparaison et un opérateur logique.
Le résultat est le suivant :
SELECT [Nom_Client] AS 'Nom Client'
,[Mail_Client] AS 'Mail Client'
FROM [Entreprise].[dbo].[Client]
WHERE Id_Client BETWEEN 1 AND 10
GO
L’instruction ci-dessus présente l’utilisation des clauses WHERE et BETWEEN, qui permet de lire
tous les enregistrements dont l’identifiant est compris entre 1 et 10 (bornes incluses). Le résultat est
le suivant :
-- Ou celle là :
Dans le premier morceau de code, nous allons afficher une seule ligne de chaque résultat,
même si plusieurs résultats existent pour la colonne Mesure, et nous comptons le nombre
d’occurrence qui interviens pour chaque Mesure, grâce à la fonction COUNT(), associée à la clause
GROUP BY. Ce genre d’instruction peu être pratique dans le cas ou l’on veut calculer le pourcentage
de vente en fonction de la localisation d’un magasin par exemple. On n’affichera qu’une seule fois la
localisation du magasin grâce à la clause GROUP BY, et on affichera pour chaque localisation, le nombre
de vente effectuée. On peut alors facilement en déduire lequel des magasins est le plus productif. Pour
revenir à notre exemple, nous pouvons déduire du résultat que nous vendons plus d’articles à l’unité,
que tout le reste des articles.
Pour le second morceau de code, on pourra seulement afficher les résultats de façon
distincte, c'est-à-dire en évitant les doublons comme dans le premier exemple. En revanche, il ne
sera pas possible d’utiliser une fonction d’agrégation, type COUNT(), car elle doit être contenue
dans une clause GROUP BY. On obtiendra alors le résultat identique au premier exemple, hors mis le
fait que nous ne pouvons pas compter le nombre d’occurrence de chaque mesure dans la colonne
Mesure.
3.3.5 Les calculs simples
Les calculs, comme nous les appelons, regrouperont les calculs numériques mais aussi les
manipulations sur les chaines de caractères, par exemple la concaténation. Les modèles sont les
suivants :
SELECT Id_Stock,
'Quantité Produit' = Quantite * 3
FROM Stock
Ici, la quantité de chaque Stock sera multipliée par trois dans le résultat de la recherche par
l’instruction SELECT. Mais la valeur de la quantité de produit ne sera en aucun cas changer dans la
base de données.
Nous obtenons 20 enregistrements, ce qui est concluent puisque les deux tables contiennent
respectivement 10 et 2 enregistrements. Les deux syntaxes, ANSI ou classique, retournent bien
évidemment le même résultat.
Le résultat est le suivant et il est le même pour les deux instructions SQL :
Avec la close ORDER BY, nous obtiendrons le même résultat que précédemment, trié dansun
ordre différent : les enregistrements sont triés selon le champ Nom_Client de façon croissante pour le
premier lot, de façon décroissante pour le second lot. Le résultat est le suivant :
Les enregistrements sont bien rangés dans l’ordre inverse, suivant la colonne Nom_Client.
UNION
EXCEPT
Ici, on sélectionnera les colonnes Id_Stock et Quantite de la table Stock, excepté celle pour
lesquelles l’Id_Stock est égal à 3.
INTERSECT
SELECT TOP 5 *
FROM [Link]
Cette instruction permet de sélectionner 50% des enregistrements dans l’ordre de lecture des
enregistrements. Dans le cas ou nous avons utilisé un pourcentage, la close WITH TIES ne s’utilise
que si une close ORDER BY est appliquée au SELECT. Elle a pour effet de ne sélectionner les
enregistrements qu’après la mise en leur tri.
Dans l’instruction précédente, la clause INTO permet de préciser que nous allons créer une
table, ici, [Link], et que nous allons ajouter les lignes trouvées dans l’instruction SELECT, à
l’intérieur de cette nouvelle table. Il est utile de préciser que la table n’est pas définie en tant que tel
par la clause INTO, mais plus par le SELECT, car c’est cette instruction qui va donner à la table ses
caractéristiques (nombre de colonnes, type de données des colonnes…). Dans le cas où des colonnes
sont calculées, il est impératif de donner un nom à ces colonnes. Si l’on fait précéder le nom de la table
créée par un #, la table sera temporaire locale, si elle est précédée d’un ##, elle sera temporaireglobale.
On rappelle que ces deux types de tables temporaires sont stockés dans la base de données Tempdb
qui est une table prédéfinie en tant que table système dans SQL Server 2008. Les tables temporaires
locales sont accessibles que par la session qui l’a créée et disparait à la déconnexionalors que les
tables globales, elles sont ensuite accessibles par toutes les sessions, et enfin elles sont détruites lors
de la déconnexion de la dernière session à l’avoir utilisée. Ce genre de table est pratique, pour des
travaux de transferts de données, ou encore si nous avons besoin de garder les données contenues
dans une table, tout en voulant supprimer la structure de la table en question.
SELECT *
FROM [Link]
ORDER BY Nom_Client
COMPUTE COUNT(Id_Client)
Le mot clé BY de la clause COMPUTE, nous permet de retourner les sous résultats en fonction
des différentes valeurs d’une colonne spécifique. Dans l’exemple, à la suite, on peu remarquer que l’on
donne la quantité du stock, pour chaque Id_Stock en sous résultat. La colonne que l’on précise donc
après le mot clé BY, nous permet de dire, de quelle manière nous allons découper les sous résultats.
SELECT *
FROM [Link]
ORDER BY Id_Stock
COMPUTE SUM(Quantite) BY Id_Stock
USE Entreprise
GO
- Les sous requêtes qui ne renvoient qu’une seule valeur unique (sous-requête scalaire) :
- Les requêtes renvoyant une liste d’enregistrements. Elles sont utilisées avec IN, EXIST, ANY,
SOME ou encore ALL :
SELECT *
FROM [Link]
WHERE EXISTS(SELECT * FROM [Link] WHERE Id_Client = 4)
- La sous requête externe utilisée au travers de la clause WHERE, fait référence à une table de
la requête interne. Dans ce cas là, la requête externe est exécutée pour chaque ligne extraite
de la requête interne.
SELECT Nom_Client
FROM [Link]
WHERE EXISTS (SELECT Id_Client_Commande, Id_Client
FROM [Link] INNER JOIN [Link]
ON Id_Client = Id_Client_Commande)
Avec le code qui va suivre, nous allons nous proposer d’améliorer la lisibilité de notre résultat
en affichant, grâce à un PIVOT, la quantité en fonction des dépôts (1, 2, 3 ou 4). Il suffit de faire un
SELECT des valeurs que nous voulons passer en colonne. Les alias présents dans l’exemple servent
évidemment à donner un nom aux colonnes créées, car par défaut, elles n’ont pas de noms. Pour
l’instruction PIVOT, comme pour l’instruction UNPIVOT, nous allons dans un premier temps appliquer
une fonction d’agrégation à la colonne passé en paramètre de la colonne de pivot et la colonne par
laquelle nous allons effectuer le pivot après la clause FOR. La clause IN indiquerasimplement les
valeurs pour lesquelles nous allons effectuer le pivot. Il est important de remarquer que l’alias que
nous donnons au pivot n’est pas optionnel. Si vous n’en donnez pas, une erreur sera levée.
USE Entreprise
GO
SELECT Id_Stock,
[1] AS "D1",[2] AS "D2",[3] AS "D3",[4] AS "D4"
FROM [Link]
PIVOT (SUM(Quantite) FOR Id_Entrepos
IN ([1],[2],[3],[4])) AS PVT
USE Entreprise
GO
L’instruction suivante permet de valoriser cette variable via l’exécution d’une requête scalaire
:
- Atomique car la transaction constitue une unité indivisible de travail pour le serveur.
- Consistance car à la fin d’une transaction, les données montrées sont soit celles d’avant
transaction (dans le cas d’une annulation de la transaction) soit celle d’après transaction (dans
le cas d’une validation).
- Isolation, car il est possible de verrouiller (isoler) les données pendant l’exécution de la
transaction (verrouillage en lecture, en écriture, …).
- Durée car les changements apportés sur des données par une transaction sont durables (non
volatiles).
Ici, dans notre exemple, nous avons deux transactions imbriquées. Il est très important de
comprendre qu’une transaction est une unité indissociable, et que par conséquent, il est nécessaire de
terminer par un COMMIT ou ROLLBACK, la dernière transaction en date. La fermeture des transactions
se fait donc celons un modèle LIFO (Last In First Out). La dernière transaction écrite sera la première à
devoir être fermée. Pour revenir à notre exemple, on peu désormais dire que le nom client égal à
HOLLEBECQ sera changé par VASSELON, du fait du ROLLBACK TRAN qui termine la transaction 2, alors
que CASANOVA ne sera pas changé par ANDREO, dans transaction1, car celle-ci se termine par un
ROLLBACK TRAN.
Un script est un ensemble de lots, qui peut être enregistré dans un fichier dont l’extension est
.sql. Comme exemple de script, vous avez le fichier [Link], disponible en annexe de ce
cours, qui contient la structure de la base, des tables, certaines entrées de données et certains objets
de la base tels qu’une procédure stockée ou un déclencheur…
Lors de l’exécution, les traces suivantes sont affichées dans la fenêtre Messages :
4.4.3 L’instruction CASE
L’instruction CASE, permet d’attribuer des valeurs en fonction d’une condition. Voici un
exemple :
USE Entreprise
SELECT 'Anciennete' = CASE Id_Client
WHEN '3' THEN 'ANCIEN'
WHEN '2' THEN 'PAS SI VIEUX'
WHEN '1' THEN 'RECENT'
ELSE 'ON SAIT PAS TROP'
END,
Id_Client, Nom_Client
FROM [Link]
ORDER BY Anciennete
Avec un case, on peu créer simplement une colonne en donnant des conditions pour les
résultats, en fonction d’une autre colonne existante. Par exemple, ici, on détermine suivant
l’Id_Client, si le client est Ancien, Pas si vieux, Récent, ou si l’on ne sait pas.
BEGIN
--Les blocs peuvent contenir
--Des instructions ou bien d'autres blocs
END
[Link] La condition IF
La structure de condition IF permet de poser une condition à une instruction. Si la condition
est vraie, l’instruction sera exécutée. Dans le cas contraire, elle ne le sera pas. Voici un exemple
d’utilisation de cette instruction :
Dans ce script, on déclare dans un premier temps une variable @Variable de type int, et de valeur
1. On applique alors une condition IF, qui définit que s’il existe un client avec un Id égal à la valeur
de notre variable déclarée préalablement, on le supprime et on écrit que le client à bien été
supprimé. L’instruction ELSE définit en revanche que pour tous les autres cas, on écrit que le client
n’existe pas.
Dans l’onglet Messages du résultat de la requête, le message suivant est alors apparu :
(1 ligne(s) affectée(s))
Le Client 11 a bien été supprimé !
Cet exemple permet d’ajouter des clients afin que la table Client en contienne 6.
- UPDATE: Précise que des mises à jour vont être faites sur la table d’origine du curseur.
- READ ONLY: Précise qu’on se place en lecture seule.
• OPEN
Cette instruction permet de rendre le curseur utilisable, et créer des tables temporaires
associées. La variable système @@CURSOR_ROWS est valorisée après cette instruction. Sa valeur
passe de 0 à 1 après l’instruction OPEN.
- GLOBAL : la porté du curseur est globale, c'est-à-dire valable pour toute la connexion.
• FETCH
C’est l’instruction qui permet d’extraire une ligne du curseur et de valoriser les variables et leur
contenu. Après cette instruction, la variable système @@FETCH_STATUS est à 0, si toutefois le FETCH
c’est bien passé.
- NEXT: Lit la ligne suivante. C’est la seule option possible pour un INSENSITIVE CURSOR.
- PRIOR: Lit la ligne précédente.
- FIRST: Lit la première ligne.
- LAST: Lit la dernière ligne.
- ABSOLUTE p: Lit la Pième ligne de l’ensemble.
- RELATIVE p: Lit la Pième ligne à partir de la ligne courante.
• CLOSE
CLOSE Nom_Curseur
• DEALLOCATE
DEALLOCATE Nom_Curseur
Maintenant que nous avons expliqué la structure et le fonctionnement d’un curseur, nous
allons montrer un exemple concret afin de comprendre leur fonctionnement en pratique :
OPEN curseur
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @Id_Client
FETCH curseur INTO @Id_Client
END
CLOSE curseur
DEALLOCATE curseur
Dans ce cas là, le curseur va nous permettre grâce à une boucle WHILE, de parcourir tous les
Id_Client pour lesquels @@FETCH_STATUS sera égal à 0. Cette variable peu prendre trois états,
0, -1, -2, respectivement pour dire que soit l’instruction FETCH c’est déroulé normalement et a réussi,
soit pour dire que l’instruction a échouée, sinon pour dire que la ligne recherchée est manquante. En
temps normal, cette variable système est initialisée à -1. Après avoir parcouru tous les enregistrements
de la table client, il est nécessaire de fermer le curseur et de le dé allouer. Lerésultat est le
suivant pour notre base de données d’exemple, Entreprise.
Lorsqu’on veut lever une erreur, on peu soit donner l’identifiant de l’erreur en question, soit
lui donner un message particulier. Si on lui donne un message particulier comme nous l’avons fait dans
l’exemple ci-dessus, il faut automatiquement lui préciser une gravité et un état. On peut ajouter une
clause WITH à la suite de l’instruction RAISERROR, pour appliquer une des trois options possibles :
BEGIN TRY
-- ...
END TRY
BEGIN CATCH
-- ...
END CATCH
Le bloc TRY permet de regrouper ensemble toutes les instructions susceptibles de lever une
erreur. SI le cas se présente ou une instruction lève une erreur dans le bloc TRY, le contrôle est
directement donné à la première instruction du bloc CATCH.
Le bloc CATCH suit toujours le bloc TRY. Celui-ci est exécuté si et seulement si, l’exécution
d’une instruction du bloc TRY lève une erreur. Dans le bloc CATCH, le code permet de gérer l’erreur
levée. Pour obtenir des informations sur cette dernière, il est possible d’utiliser les fonctions SQL
suivantes :