Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Verwenden Sie SCOPE_IDENTITY(), um den zuletzt eingefügten Identitätswert im selben Bereich zurückzugeben (SQL Server)

In SQL Server können Sie T-SQL SCOPE_IDENTITY() verwenden -Funktion, um den letzten Identitätswert zurückzugeben, der in eine Identitätsspalte im selben Bereich eingefügt wurde.

Ein Bereich ist ein Modul (gespeicherte Prozedur, Trigger, Funktion oder Batch). Wenn sich zwei Anweisungen in derselben gespeicherten Prozedur, Funktion oder demselben Stapel befinden, befinden sie sich im selben Geltungsbereich.

Beachten Sie, dass es den letzten Identitätswert zurückgibt, der in einer beliebigen Tabelle in der aktuellen Sitzung generiert wurde . Dies steht im Gegensatz zu IDENT_CURRENT() -Funktion, die den zuletzt eingefügten Identitätswert für eine bestimmte Tabelle zurückgibt , unabhängig davon, in welcher Sitzung es sich befindet.

SCOPE_IDENTITY() ist sehr ähnlich zu @@IDENTITY , dass sie beide den zuletzt eingefügten Identitätswert in der aktuellen Sitzung zurückgeben. Der Unterschied besteht darin, dass SCOPE_IDENTITY() ist auf den aktuellen Geltungsbereich beschränkt, wohingegen @@IDENTITY ist nicht auf einen bestimmten Geltungsbereich beschränkt.

Beispiel 1 – Grundlegende Verwendung

Hier ist ein einfaches Codebeispiel, wie es funktioniert.

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

Ergebnis:

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

Der Grund für das NULL-Ergebnis liegt darin, dass ich die Anweisung unmittelbar nach dem Öffnen einer neuen Verbindung zu SQL Server ausgeführt habe. Der SCOPE_IDENTITY() Funktion gibt nur Ergebnisse aus der aktuellen Sitzung zurück.

Um also ein Nicht-NULL-Ergebnis zu erhalten, muss ich einen Wert in eine Identitätsspalte einfügen.

Beispiel 2 – Einfügen eines Werts für ein Nicht-NULL-Ergebnis

In diesem Beispiel erstelle ich eine Tabelle mit einer Identitätsspalte. Ich füge dann einen Standardwert in diese Tabelle ein, bevor ich den Inhalt der Tabelle auswähle und dann SCOPE_IDENTITY() ausführe nochmal.

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];

Ergebnis:

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

Die Tabelle hat eine Zeile und ihre Identitätsspalte hat einen Wert von 1. Dies ist der zuletzt eingefügte Identitätswert für die aktuelle Sitzung, also SCOPE_IDENTITY() gibt auch 1 zurück.

Wenn ich jetzt eine weitere Zeile hinzufüge, erhöht sich der Wert entsprechend:

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

Ergebnis:

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

Ergebnisse einer neuen Sitzung

Wie bereits erwähnt, SCOPE_IDENTITY() gibt nur Ergebnisse aus derselben Sitzung zurück. Dies gilt auch für @@IDENTITY .

Wenn ich also eine neue Verbindung zu SQL Server öffne und das vorherige SELECT ausführe Anweisungen erhalte ich folgende Ergebnisse:

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

Ergebnis:

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

Lassen Sie uns nun eine neue Zeile aus dieser neuen Sitzung einfügen:

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

Ergebnis:

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

Also hat es aufgeholt, sobald ich einen neuen Identitätswert eingefügt habe.

Wechseln wir jedoch zurück zur ursprünglichen Sitzung und führen Sie SELECT aus Anweisungen erneut (ohne eine neue Zeile einzufügen):

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

Ergebnis:

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

Also die SCOPE_IDENTITY() der ursprünglichen Sitzung Die Ergebnisse wurden durch die zweite Sitzung nicht beeinflusst.

Hinzufügen eines zweiten Bereichs

Das Ding, das SCOPE_IDENTITY() unterscheidet von @@IDENTITY , ist das SCOPE_IDENTITY() ist auf den aktuellen Umfang beschränkt.

Wenn die Tabelle beispielsweise einen Trigger hat, der einen Identitätswert in eine andere Tabelle einfügt, SCOPE_IDENTITY() würde nur den ersten Identitätswert melden. Es würde den Identitätswert für die zweite Tabelle ignorieren, da dieser in einem anderen Geltungsbereich @@IDENTITY erstellt wurde würde andererseits den Identitätswert für die zweite Tabelle melden (weil er alle Bereiche abdeckt).

Ein Beispiel dafür, was ich meine, finden Sie unter IDENT_CURRENT vs. @@IDENTITY vs. SCOPE_IDENTITY in SQL Server:Was ist der Unterschied?

Dieser Artikel geht durch ein Trigger-Beispiel wie das, worüber ich hier spreche.