Lorsqu'on utilise un compteur dans SQL Server pour gérer l'auto incrémentation d'un champ (IDENTITY) on a souvent la problématique suivante : comment récupérer la valeur du champs auto incrémenté lorque nous effectuons une insertion.
Nous avons plusieurs solutions :
- SCOPE_IDENTITY
- IDENT_CURRENT
- @@IDENTITY
Face à un tel choix, dur de choisir... Pas tant que ça! Vous vous doutez bien que chaque solution à ses particularités.
IDENT_CURRENT renvoi bel et bien le dernier élément inséré. C'est d'ailleurs cette fonction qui donne la réponse la plus exacte mais qui ne nous intéressera pas dans ce cas-ci quand elle renvoi le dernier sans se soucier de la session et de l'étendue. Prenons un exemple pour voir où serait le problème :
Nous avons deux utilisateurs : X et Y. Ces deux utilisateurs font appel à une procédure stockée qui fait un INSERT et renvoi la valeur du champ auto incrémenté.
A l'instant T, nous avons donc deux exécution de notre procédure stockée qui nous appellerons : PROC A et PROC B. Dans un premier temps c'est PROC A qui prend la main et qui fait l'ajout. La valeur que devrait renvoyé la procédure stockée est "1" mais avant de faire IDENT_CURRENT(), PROC B prend la main (pas de chance hein?) et utilise donc le compteur qui à maintenant la valeur 2. PROC A reprend la main et arrive à IDENT_CURRENT() qui renvoi... 2 alors qu'on voudrai bien avoir en valeur de retour 1. Problème tout aussi grave, lorsque PROC B prend la main pour terminer la procédure, elle renvoi, elle aussi, 2! On a bien la dernière valeur du compteur mais cela ne nous intéresse pas dans notre cas! On aurait aimé que PROC A renvoi 1 et PROC B -> 2. Notez que cela aurait pu se produire... ou pas, c'est ça le problème.
On voit souvent @@IDENTITY comme solution sur les forums et blogs. En effet, @@IDENTITY renvoi la valeur en tenant compte de la session. Ainsi, le cas de IDENT_CURRENT ne peut pas arriver avec @@IDENTITY. Malheureusement, il existe des situations un peu plus complexe où ne pourrions pas compter sur @@IDENTITY car celui-ci ne regarde pas à l'étendue de la requête. Je vous laisse imaginer le cas problématique où nous aurions deux champs auto incrémentés dans deux tables différentes mais directement liées par un déclencheur (lors de l'ajout dans T1, un déclencheur déclenche un ajout dans T2). Si le but de la procédure stockée est de renvoyé les deux valeurs des champs auto incrémentés, alors on risque d'avoir des valeurs assez nébuleuses.
Du coup, c'est SCOPE_IDENTITY qui convient le mieux dans notre cas car cette fonction prend en compte la session et l'étendue.
Pour résumer :
SCOPE_IDENTITY : prend en compte la table, l'étendue et la session IDENT_CURRENT : prend en compte uniquement la table @@IDENTITY : prend en compte la table et la session. NB : Merci à Aurélien Verla qui m'a fait découvrir SCOPE_IDENTITY et sa nuance avec @@IDENTITY :-)
Lire la suite...
Tags:
sql
Catégorie :
SQL Server |
T-SQL
Une question sur cet article? n'hésitez pas a me contacter par Live Messegner. Suis-je connecté? 
Soyez le premier à noter ce billet
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
Permalink |
Commentaires (3) |
Post RSS |