Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY dans SQL Server :Quelle est la différence ?

Dans SQL Server, si jamais vous avez besoin de retourner la valeur créée dans une colonne d'identité, vous avez plusieurs options. Chacune de ces options, bien que similaire, fait une chose légèrement différente.

Vous pouvez notamment utiliser les fonctions suivantes :

  • IDENT_CURRENT() renvoie la dernière valeur d'identité insérée pour une table donnée.
  • SCOPE_IDENTITY() renvoie la dernière valeur d'identité insérée dans une colonne d'identité dans any table dans la session en cours et la portée actuelle.
  • @@IDENTITY renvoie la dernière valeur d'identité insérée dans any table dans la session en cours, quelle que soit la portée.

Exemple

Voici un exemple qui montre la différence entre ces trois fonctions.

Tout d'abord, créez deux tables. Notez les différentes valeurs de départ et d'incrément utilisées pour la colonne d'identité dans chaque table :

CREATE TABLE t1(id int IDENTITY(1,1));  
CREATE TABLE t2(id int IDENTITY(150,10));

Créez maintenant un déclencheur qui insère une ligne dans le deuxième tableau chaque fois qu'une ligne est insérée dans le premier tableau :

CREATE TRIGGER t1_insert_trigger ON t1 FOR INSERT
AS
BEGIN
  INSERT t2 DEFAULT VALUES
END;

Les déclencheurs se déclenchent dans une portée différente, donc c'est parfait pour mon exemple ici.

Insérez des données dans le premier tableau, puis sélectionnez les résultats des deux tableaux :

INSERT t1 DEFAULT VALUES;
SELECT id AS t1 FROM t1;
SELECT id AS t2 FROM t2;

Résultat :

+------+
| t1   |
|------|
| 1    |
+------+
(1 row affected)
+------+
| t2   |
|------|
| 150  |
+------+
(1 row affected)

Donc, juste pour être clair, ces données ont été insérées par deux portées différentes. L'insertion dans t1 a été fait par la portée actuelle. L'insertion dans t2 a été effectué par le déclencheur, qui s'est exécuté dans une portée différente.

Choisissons maintenant parmi les fonctions mentionnées précédemment :

SELECT 
  @@IDENTITY AS [@@IDENTITY],
  SCOPE_IDENTITY() AS [SCOPE_IDENTITY()],
  IDENT_CURRENT('t1') AS [IDENT_CURRENT('t1')],
  IDENT_CURRENT('t2') AS [IDENT_CURRENT('t2')];

Résultat :

+--------------+--------------------+-----------------------+-----------------------+
| @@IDENTITY   | SCOPE_IDENTITY()   | IDENT_CURRENT('t1')   | IDENT_CURRENT('t2')   |
|--------------+--------------------+-----------------------+-----------------------|
| 150          | 1                  | 1                     | 150                   |
+--------------+--------------------+-----------------------+-----------------------+

Le résultat renvoyé par @@IDENTITY n'est pas limité à la portée et renvoie donc la dernière valeur d'identité insérée, quelle que soit la portée.

SCOPE_IDENTITY() renvoie la valeur d'identité de la première table, car il s'agissait de la dernière valeur d'identité insérée dans la portée actuelle (le déclencheur est en dehors de la portée actuelle).

Le IDENT_CURRENT() La fonction renvoie simplement la dernière valeur d'identité insérée dans la table spécifiée, quelle que soit la portée ou la session.

Ouvrir une nouvelle session

Maintenant, voici ce qui se passe si j'ouvre une nouvelle session et que j'exécute à nouveau l'instruction précédente :

USE Test;
SELECT 
  @@IDENTITY AS [@@IDENTITY],
  SCOPE_IDENTITY() AS [SCOPE_IDENTITY()],
  IDENT_CURRENT('t1') AS [IDENT_CURRENT('t1')],
  IDENT_CURRENT('t2') AS [IDENT_CURRENT('t2')];

Résultat :

+--------------+--------------------+-----------------------+-----------------------+
| @@IDENTITY   | SCOPE_IDENTITY()   | IDENT_CURRENT('t1')   | IDENT_CURRENT('t2')   |
|--------------+--------------------+-----------------------+-----------------------|
| NULL         | NULL               | 1                     | 150                   |
+--------------+--------------------+-----------------------+-----------------------+

Les deux @@IDENTITY et SCOPE_IDENTITY() sont NULL car ils ne renvoient que les résultats de la session en cours. Je n'ai effectué aucune insertion de colonne d'identité dans cette nouvelle session, j'obtiens donc NULL.

IDENT_CURRENT() d'autre part, renvoie le même résultat que dans l'exemple précédent, encore une fois parce que ses résultats sont basés sur la table spécifiée, quelle que soit la session ou la portée.