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

IDENT_CURRENT vs. @@IDENTITY vs. SCOPE_IDENTITY in SQL Server:Was ist der Unterschied?

Wenn Sie in SQL Server jemals den in einer Identitätsspalte erstellten Wert zurückgeben müssen, haben Sie mehrere Möglichkeiten. Jede dieser Optionen, obwohl ähnlich, macht etwas anderes.

Insbesondere können Sie folgende Funktionen nutzen:

  • IDENT_CURRENT() gibt den zuletzt eingefügten Identitätswert für eine gegebene Tabelle zurück.
  • SCOPE_IDENTITY() gibt den letzten Identitätswert zurück, der in beliebig in eine Identitätsspalte eingefügt wurde Tabelle in der aktuellen Sitzung und im aktuellen Umfang.
  • @@IDENTITY gibt den zuletzt eingefügten Identitätswert in beliebig zurück Tabelle in der aktuellen Sitzung, unabhängig vom Bereich.

Beispiel

Hier ist ein Beispiel, das den Unterschied zwischen diesen drei Funktionen demonstriert.

Erstellen Sie zunächst zwei Tabellen. Beachten Sie die unterschiedlichen Seed- und Inkrementwerte, die für die Identitätsspalte in jeder Tabelle verwendet werden:

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

Erstellen Sie nun einen Trigger, der eine Zeile in die zweite Tabelle einfügt, wenn eine Zeile in die erste Tabelle eingefügt wird:

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

Löst Feuer in einem anderen Bereich aus, also ist das perfekt für mein Beispiel hier.

Fügen Sie Daten in die erste Tabelle ein und wählen Sie dann die Ergebnisse aus beiden Tabellen aus:

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

Ergebnis:

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

Nur um das klarzustellen, diese Daten wurden von zwei verschiedenen Bereichen eingefügt. Die Einfügung in t1 wurde mit dem aktuellen Umfang durchgeführt. Die Einfügung in t2 wurde vom Trigger ausgeführt, der in einem anderen Bereich lief.

Wählen wir nun aus den zuvor erwähnten Funktionen:

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

Ergebnis:

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

Das von @@IDENTITY zurückgegebene Ergebnis ist nicht auf den Bereich beschränkt und gibt daher unabhängig vom Bereich den zuletzt eingefügten Identitätswert zurück.

SCOPE_IDENTITY() gibt den Identitätswert aus der ersten Tabelle zurück, da dies der letzte eingefügte Identitätswert innerhalb des aktuellen Geltungsbereichs war (der Trigger liegt außerhalb des aktuellen Geltungsbereichs).

Der IDENT_CURRENT() Die Funktion gibt einfach den zuletzt in die angegebene Tabelle eingefügten Identitätswert zurück, unabhängig von Bereich oder Sitzung.

Öffnen Sie eine neue Sitzung

Folgendes passiert nun, wenn ich eine neue Sitzung öffne und die vorherige Anweisung erneut ausführe:

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

Ergebnis:

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

Beides @@IDENTITY und SCOPE_IDENTITY() sind NULL, da sie nur Ergebnisse aus der aktuellen Sitzung zurückgeben. Ich habe in dieser neuen Sitzung keine Identitätsspalteneinfügungen durchgeführt, daher erhalte ich NULL.

IDENT_CURRENT() gibt andererseits das gleiche Ergebnis wie im vorherigen Beispiel zurück, wieder weil seine Ergebnisse auf der angegebenen Tabelle basieren, unabhängig von Sitzung oder Bereich.