Il m'arrive souvent de répondre à la question suivante : Quelle est la différence entre @@IDENTITY et SCOPE_IDENTITY() ?? Est-ce la portée (locale à la connexion ou globale) ??
La différence n'est pas un problème de portée au sens environnement de connexion mais plus au niveau cascading.
Je m'explique. Tout d'abord rappelons que ces deux fonctions permettent de renvoyer la valeur de l'identity de la dernière insertion effectuée dans une connexion.
Soit deux table :
CREATE TABLE [dbo].[T1](
Id [int] IDENTITY(1,1) NOT NULL,
name [nchar](10) NULL,
CONSTRAINT [PK_T1] PRIMARY KEY CLUSTERED ([Id] ASC)
Et
CREATE TABLE [dbo].[T2](
Id [int] IDENTITY(1,1) NOT NULL,
name [nchar](10) NULL,
CONSTRAINT [PK_T2] PRIMARY KEY CLUSTERED ([Id] ASC)
On souhaite faire une insertion dans T2 à partir d'un trigger de type AFTER INSERT dans T1. Notre trigger ressemblerait a ça :
CREATE TRIGGER [dbo].[TR_T1] ON [dbo].[T1]
AFTER INSERT
AS
BEGIN
INSERT INTO T2(name) VALUES ('test')
END
Nous insérons 5 lignes dans T2 directement pour avoir un numéro d'identity différent de celui de T1. A ce moment,
Enfin, on effectue notre insertion dans T1 et on récupère l'identity avec nos deux méthodes :
INSERT INTO T1(name) VALUES ('test')
PRINT @@IDENTITY
PRINT SCOPE_IDENTITY()
Et le résultat :
(1 ligne(s) affectée(s))
(1 ligne(s) affectée(s))
6
1
Et oui ! le @@IDENTITY renvoie le dernier identity inséré quelque soit le niveau dans lequel cette insertion s'est faite. Le SCOPE_IDENTITY() va toujours faire référence à l'insertion du niveau dans lequel cette fonction est exécutée.
En conclusion, si vous n'êtes pas sûr de l'existence de triggers sous-jacents, préférez SCOPE_IDENTITY pour ne pas avoir de mauvaise surprise....
A noter également la fonction
SELECT IDENT_CURRENT('nom_table')
qui renvoie l'identity de la dernière insertion, toute session confondue pour une table nom_table donnée.
A bientôt...