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

Utilisez SCOPE_IDENTITY() pour renvoyer la dernière valeur d'identité insérée dans la même étendue (SQL Server)

Dans SQL Server, vous pouvez utiliser le T-SQL SCOPE_IDENTITY() fonction pour renvoyer la dernière valeur d'identité insérée dans une colonne d'identité dans la même portée.

Une portée est un module (procédure stockée, déclencheur, fonction ou batch). Si deux instructions se trouvent dans la même procédure stockée, la même fonction ou le même lot, elles sont dans la même portée.

Notez qu'il renvoie la dernière valeur d'identité générée dans n'importe quelle table de la session en cours . Ceci est en contraste avec le IDENT_CURRENT() fonction, qui renvoie la dernière valeur d'identité insérée pour une table donnée , quelle que soit la session dans laquelle il se trouve.

SCOPE_IDENTITY() est très similaire à @@IDENTITY en ce qu'ils renvoient tous les deux la dernière valeur d'identité insérée dans la session en cours. La différence est que SCOPE_IDENTITY() est limité à la portée actuelle, alors que @@IDENTITY n'est pas limité à une portée spécifique.

Exemple 1 - Utilisation de base

Voici un exemple de code de base de la façon dont cela fonctionne.

SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Résultat :

+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| NULL                           |
+--------------------------------+

La raison du résultat NULL est que j'ai exécuté l'instruction immédiatement après l'ouverture d'une nouvelle connexion à SQL Server. Le SCOPE_IDENTITY() la fonction ne renvoie que les résultats de la session en cours.

Donc, pour obtenir un résultat non NULL, je dois insérer une valeur dans une colonne d'identité.

Exemple 2 - Insérer une valeur pour un résultat non NULL

Dans cet exemple, je crée une table avec une colonne d'identité. J'insère ensuite une valeur par défaut dans cette table avant de sélectionner le contenu de la table, puis d'exécuter SCOPE_IDENTITY() à nouveau.

CREATE TABLE scope_identity_test(id int IDENTITY(1,1));
INSERT scope_identity_test DEFAULT VALUES;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Résultat :

+------+
| id   |
|------|
| 1    |
+------+
(1 row affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 1                              |
+--------------------------------+
(1 row affected)

La table a une ligne et sa colonne d'identité a une valeur de 1. Il s'agit de la dernière valeur d'identité insérée pour la session en cours, et donc SCOPE_IDENTITY() renvoie également 1.

Maintenant, si j'ajoute une autre ligne, la valeur augmente en conséquence :

INSERT scope_identity_test DEFAULT VALUES;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Résultat :

+------+
| id   |
|------|
| 1    |
| 2    |
+------+
(2 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 2                              |
+--------------------------------+
(1 row affected)

Résultats d'une nouvelle session

Comme mentionné, SCOPE_IDENTITY() ne renvoie que les résultats de la même session. Ceci est également vrai pour @@IDENTITY .

Donc, si j'ouvre une nouvelle connexion à SQL Server et que j'exécute le précédent SELECT instructions à nouveau, j'obtiens les résultats suivants :

USE Test;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Résultat :

+------+
| id   |
|------|
| 1    |
| 2    |
+------+
(2 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| NULL                           |
+--------------------------------+
(1 row affected)

Insérons maintenant une nouvelle ligne à partir de cette nouvelle session :

INSERT scope_identity_test DEFAULT VALUES;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Résultat :

+------+
| id   |
|------|
| 1    |
| 2    |
| 3    |
+------+
(1 row affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 3                              |
+--------------------------------+
(3 rows affected)

Donc, il a rattrapé dès que j'ai inséré une nouvelle valeur d'identité.

Cependant, revenons à la session d'origine et exécutons le SELECT à nouveau (sans insérer de nouvelle ligne) :

SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Résultat :

+------+
| id   |
|------|
| 1    |
| 2    |
| 3    |
+------+
(3 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 2                              |
+--------------------------------+
(1 row affected)

Ainsi, le SCOPE_IDENTITY() de la session d'origine les résultats n'ont pas été affectés par la deuxième session.

Ajout d'un deuxième champ d'application

La chose qui différencie SCOPE_IDENTITY() de @@IDENTITY , est-ce que SCOPE_IDENTITY() est limité au périmètre actuel.

Par exemple, si la table a un déclencheur qui insère une valeur d'identité dans une autre table, SCOPE_IDENTITY() ne rapporterait que la première valeur d'identité. Il ignorerait la valeur d'identité de la deuxième table, car celle-ci a été créée dans une portée différente @@IDENTITY d'autre part, indiquerait la valeur d'identité pour la deuxième table (car elle couvre toutes les portées).

Pour un exemple de ce que je veux dire, consultez IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY dans SQL Server :Quelle est la différence ?

Cet article présente un exemple de déclencheur comme celui dont je parle ici.