65 votes

@@IDENTITY, SCOPE_IDENTITY(), OUTPUT et autres méthodes de récupération de la dernière identité

J'ai vu différentes méthodes utilisées pour récupérer la valeur d'un champ d'identité de clé primaire après insertion.

declare @t table (
    id int identity primary key,
    somecol datetime default getdate()
)
insert into @t
default values

select SCOPE_IDENTITY() --returns 1
select @@IDENTITY --returns 1

Renvoi d'une table d'identités à la suite d'un encart :

Create Table #Testing (  
    id int identity,  
    somedate datetime default getdate()  
)  
insert into #Testing  
output inserted.*  
default values   

Quelle est la méthode la plus appropriée ou la meilleure ? La méthode OUTPUT est-elle sans danger pour le champ d'application ?

Le deuxième extrait de code a été emprunté à SQL dans la nature

77voto

mson Points 4828

Cela dépend de ce que vous essayez de faire...

@@IDENTITY

Renvoie la dernière valeur d'IDENTITÉ produite sur une connexion, quelle que soit la table qui a produit la valeur et quelle que soit la portée de l'instruction qui a produit la valeur. @@IDENTITY renvoie la dernière valeur d'identité entrée dans une table dans la session en cours. @@IDENTITY est limité à la session en cours et n'est pas limité à la portée en cours. Par exemple, si vous avez un déclencheur sur une table qui provoque la création d'une identité dans une autre table, vous obtiendrez l'identité qui a été créée en dernier, même si c'est le déclencheur qui l'a créée.

IDENTITÉ DU CHAMP D'APPLICATION()

Renvoie la dernière valeur d'IDENTITÉ produite sur une connexion et par une instruction dans la même portée, quelle que soit la table qui a produit la valeur. SCOPE_IDENTITY() est similaire à @@IDENTITY, mais il limitera également la valeur à votre portée actuelle. En d'autres termes, elle renverra la dernière valeur d'identité que vous avez explicitement créée, plutôt qu'une identité créée par un déclencheur ou une fonction définie par l'utilisateur.

IDENT_CURRENT()

Renvoie la dernière valeur d'IDENTITÉ produite dans une table, indépendamment de la connexion et de la portée de l'instruction qui a produit la valeur. IDENT_CURRENT est limité à une table spécifiée, mais pas par la connexion ou l'étendue.

25 votes

Vous n'avez pas décrit l'utilisation de OUTPUT qui est la méthode préférée dans les nouvelles versions de SQL Server. Non seulement elle est sans danger pour le champ d'application, mais elle peut renvoyer plusieurs identités et même d'autres champs si vous en avez besoin pour un traitement ultérieur.

4 votes

@HLGEM, OUTPUT est bien, mais un peu difficile à utiliser quand on a besoin d'une seule valeur d'identité.

0 votes

@Constantin, bien que cela soit vrai, c'est la façon préférée de Microsoft d'obtenir la valeur et, d'après ce que j'ai lu, ils n'ont pas l'intention de résoudre les problèmes avec @@identity et scope_Identity à l'avenir, car ils considèrent OUTPUT comme le remplacement.

15voto

Simon D Points 1453

Notez qu'il y a un bogue dans scope_identity() y @@identity - voir MS Connect : https://web.archive.org/web/20130412223343/https://connect.microsoft.com/SQLServer/feedback/details/328811/scope-identity-sometimes-returns-incorrect-value

Une citation (de Microsoft) :

Je recommande vivement d'utiliser OUTPUT au lieu de @@IDENTITY dans tous les cas. C'est simplement la meilleure façon de lire l'identité et l'horodatage.

Éditée pour ajouter : ceci est peut-être corrigé maintenant. Connect me donne une erreur, mais je vois :

Correction de Scope_Identity() qui renvoie une valeur incorrecte ?

0 votes

Je voulais juste mentionner que le bogue ci-dessus se produit lorsque le parallélisme est utilisé. Mais cela n'affecterait pas les cas où une seule insertion est effectuée. Voici une citation de Microsoft. "Chaque fois qu'un plan de requête parallèle est généré, @@IDENTITY et SCOPE_IDENTITY() ne sont pas mis à jour de manière cohérente et on ne peut pas s'y fier.

0 votes

Qu'en est-il de SCOPE_IDENTITY() ? Il semble que @@IDENTITY ait toujours été problématique pour plus de cas d'utilisation.

6voto

jcollum Points 10236

@@Identity est la bonne vieille méthode. Utilisez SCOPE_IDENTITY() dans toutes les instances à l'avenir. Voir MSDN pour les répercussions de l'utilisation de @@IDENTITY (elles sont mauvaises !).

0 votes

Même SCOPE_IDENTITY() a des problèmes avec les déclencheurs qui effectuent leurs propres insertions. (vous donne l'identité de la dernière table dans laquelle les déclencheurs ont inséré).

0 votes

Ce lien contient un exemple de code qui semble contredire votre affirmation. Il est à peu près certain que les déclencheurs se produisent dans un champ d'application différent.

2 votes

@Dems, ce n'est absolument pas vrai

3voto

Terrapin Points 15061

Il existe une autre méthode disponible dans SQL Server 2005 qui est décrite ci-dessous dans SQL in the Wild .

Cela vous permettra de récupérer plusieurs identités après l'insertion. Voici le code de l'article de blog :

Create Table #Testing (  
    id int identity,  
    somedate datetime default getdate()  
)  
insert into #Testing  
output inserted.*  
default values

0 votes

J'ai déjà vu cela auparavant, mais j'ai supposé que ce n'était pas sûr pour le champ d'application. Cela signifie que je pourrais voir les insertions de quelqu'un d'autre. Je ne sais pas si c'est vrai.

0 votes

Je n'en suis pas certain. Je l'ajouterai à la question.

4 votes

La sortie est sans danger pour le champ d'application. C'est la méthode préférée à partir de maintenant.

3voto

Paul Sasik Points 37766

Une petite correction à la réponse de Godeke :

Il n'y a pas que les déclencheurs dont il faut se préoccuper. Tout type d'opération imbriquée, telle que les procs stockées, qui entraîne la création d'identifiants peut modifier la valeur de @@IDENTITY.

Un autre vote pour scope_identity...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X