1383 votes

SQL Server - Meilleur moyen d'obtenir l'identité d'une ligne insérée ?

Quel est le meilleur moyen d'obtenir IDENTITY de la ligne insérée ?

Je suis au courant @@IDENTITY y IDENT_CURRENT y SCOPE_IDENTITY mais ne comprennent pas les avantages et les inconvénients de chacun.

Quelqu'un peut-il m'expliquer les différences et me dire quand je dois les utiliser ?

1740voto

bdukes Points 54833
  • @@IDENTITY renvoie la dernière valeur d'identité générée pour n'importe quelle table dans la session actuelle, tous scopes confondus. Vous devez être prudent ici puisque c'est une question de portée. Vous pourriez obtenir une valeur à partir d'un déclencheur, au lieu de votre déclaration actuelle.

  • SCOPE_IDENTITY() renvoie la dernière valeur d'identité générée pour n'importe quelle table de la session actuelle et de l'étendue actuelle. En général, ce que vous voulez utiliser .

  • IDENT_CURRENT('tableName') renvoie la dernière valeur d'identité générée pour une table spécifique dans n'importe quelle session et n'importe quelle portée. Cela vous permet de spécifier de quelle table vous voulez la valeur, au cas où les deux ci-dessus ne correspondent pas tout à fait à vos besoins ( très rare ). De même, comme @ Guy Starbuck a mentionné : "Vous pouvez utiliser cette fonction si vous souhaitez obtenir la valeur d'IDENTITÉ actuelle pour une table dans laquelle vous n'avez pas inséré d'enregistrement."

  • Le site OUTPUT clause de la INSERT vous permettra d'accéder à chaque ligne qui a été insérée via cette instruction. Puisqu'il s'agit de l'instruction spécifique, il s'agit de plus simple que les autres fonctions ci-dessus. Cependant, c'est un peu plus verbeux (vous devrez insérer dans une variable de table/temp table et ensuite interroger cette dernière) et cela donne des résultats même dans un scénario d'erreur où la déclaration est annulée. Cela dit, si votre requête utilise un plan d'exécution parallèle, il s'agit de la méthode la plus efficace. seule méthode garantie pour obtenir l'identité (sans désactiver le parallélisme). Cependant, il est exécuté antes de et ne peut pas être utilisé pour renvoyer des valeurs générées par les déclencheurs.

227voto

Orry Points 659

Je pense que la méthode la plus sûre et la plus précise pour récupérer l'identifiant inséré serait d'utiliser la clause de sortie.

par exemple (extrait de ce qui suit MSDN article)

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

135voto

Orion Edwards Points 54939

Je dis la même chose que les autres, donc tout le monde a raison, j'essaie juste de rendre les choses plus claires.

@@IDENTITY renvoie l'identifiant de la dernière chose qui a été insérée par la connexion de votre client à la base de données.
La plupart du temps, cela fonctionne bien, mais il arrive qu'un déclencheur insère une nouvelle ligne dont vous n'êtes pas au courant, et vous obtenez l'ID de cette nouvelle ligne, au lieu de celui que vous voulez.

SCOPE_IDENTITY() résout ce problème. Il renvoie l'identifiant de la dernière chose que vous avez inséré dans le code SQL vous avez envoyé à la base de données. Si les déclencheurs créent des lignes supplémentaires, ils n'entraîneront pas le renvoi d'une valeur erronée. Hourra

IDENT_CURRENT renvoie le dernier ID qui a été inséré par quelqu'un. Si une autre application insère une autre ligne au mauvais moment, vous obtiendrez l'ID de cette ligne au lieu de la vôtre.

Si vous voulez jouer la carte de la sécurité, utilisez toujours SCOPE_IDENTITY() . Si vous vous en tenez à @@IDENTITY et que quelqu'un décide d'ajouter un déclencheur plus tard, tout votre code sera cassé.

77voto

Ian Kemp Points 6408

La meilleure façon (lisez : la plus sûre) d'obtenir l'identité d'une ligne nouvellement insérée est d'utiliser la commande output clause :

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

25voto

Jakub Šturc Points 12549

De MSDN

@@IDENTITY, SCOPE_IDENTITY et IDENT_CURRENT sont des fonctions similaires dans la mesure où elles renvoient la dernière valeur insérée dans la colonne IDENTITY d'une table.

@@IDENTITY et SCOPE_IDENTITY renvoient la dernière valeur d'identité générée dans n'importe quelle table de la session en cours. Cependant, SCOPE_IDENTITY renvoie la valeur uniquement dans la portée actuelle ; @@IDENTITY n'est pas limitée à une portée spécifique.

IDENT_CURRENT n'est pas limité par la portée et la session ; il est limité à une table spécifiée. IDENT_CURRENT renvoie la valeur d'identité générée pour une table spécifique dans n'importe quelle session et n'importe quelle portée. Pour plus d'informations, voir IDENT_CURRENT.

  • IDENT_CURRENT est une fonction qui prend un tableau comme argument.
  • @@IDENTITY peut renvoyer un résultat confus lorsque vous avez un déclencheur sur la table.
  • SCOPE_IDENTITY est votre héros la plupart du temps.

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