it-swarm.com.de

Was ist der Unterschied zwischen Scope_Identity (), Identity (), @@ Identity und Ident_Current ()?

Ich weiß, dass Scope_Identity(), Identity(), @@Identity Und Ident_Current() alle den Wert der Identitätsspalte erhalten, aber ich würde gerne den Unterschied kennen .

Ein Teil der Kontroverse, die ich habe, ist, was bedeuten sie mit dem Umfang, wie er auf diese oben genannten Funktionen angewendet wird?

Ich würde auch gerne ein einfaches Beispiel für verschiedene Anwendungsszenarien sehen.

167
Tebo
  • Die Funktion @@identity Gibt die letzte in derselben Sitzung erstellte Identität zurück.
  • Die Funktion scope_identity() gibt die letzte Identität zurück, die in derselben Sitzung und demselben Bereich erstellt wurde.
  • Die Funktion ident_current(name) gibt die letzte Identität zurück, die für eine bestimmte Tabelle oder Sicht in einer Sitzung erstellt wurde.
  • Die Funktion identity() wird nicht zum Abrufen einer Identität verwendet, sondern zum Erstellen einer Identität in einer select...into - Abfrage.

Die Sitzung ist die Datenbankverbindung. Der Bereich ist die aktuelle Abfrage oder die aktuelle gespeicherte Prozedur.

Eine Situation, in der sich die Funktionen scope_identity() und @@identity Unterscheiden, liegt vor, wenn Sie einen Auslöser für die Tabelle haben. Wenn Sie eine Abfrage haben, bei der ein Datensatz eingefügt wird und der Trigger irgendwo einen anderen Datensatz einfügt, gibt die Funktion scope_identity() die von der Abfrage erstellte Identität zurück, während die Funktion @@identity Die Identität zurückgibt erstellt durch den Trigger.

Normalerweise würden Sie also die Funktion scope_identity() verwenden.

337
Guffa

Gute Frage.

  • @@IDENTITY: Gibt den letzten Identitätswert zurück, der für Ihre SQL-Verbindung (SPID) generiert wurde. Meistens ist es das, was Sie wollen, aber manchmal nicht (wie wenn ein Trigger als Antwort auf eine INSERT ausgelöst wird und der Trigger eine andere INSERT -Anweisung ausführt).

  • SCOPE_IDENTITY(): Gibt den letzten im aktuellen Bereich generierten Identitätswert zurück (d. h. gespeicherte Prozedur, Trigger, Funktion usw.).

  • IDENT_CURRENT(): Gibt den letzten Identitätswert für eine bestimmte Tabelle zurück. Verwenden Sie dies nicht, um den Identitätswert von einem INSERT zu erhalten, da dies von Race-Bedingungen abhängt (d. H. Mehrere Verbindungen, die Zeilen in dieselbe Tabelle einfügen).

  • IDENTITY(): Wird verwendet, wenn eine Spalte in einer Tabelle als Identitätsspalte deklariert wird.

Weitere Informationen finden Sie unter: http://msdn.Microsoft.com/en-us/library/ms187342.aspx .

Zusammenfassend: Wenn Sie Zeilen einfügen und den Wert der Identitätsspalte für die gerade eingefügte Zeile you kennen möchten, verwenden Sie immer SCOPE_IDENTITY().

40
Brannon

Wenn Sie den Unterschied zwischen Umfang und Sitzung verstehen, ist es sehr einfach, diese Methoden zu verstehen.

A very Nice Blogpost von Adam Anderson beschreibt diesen Unterschied:

Sitzung bezeichnet die aktuelle Verbindung, die den Befehl ausführt.

Bereich bezeichnet den unmittelbaren Kontext eines Befehls. Jeder Aufruf einer gespeicherten Prozedur wird in einem eigenen Bereich ausgeführt, und verschachtelte Aufrufe werden in einem verschachtelten Bereich innerhalb des Bereichs der aufrufenden Prozedur ausgeführt. Ebenso wird ein SQL-Befehl, der von einer Anwendung oder einem SSMS ausgeführt wird, in seinem eigenen Bereich ausgeführt. Wenn dieser Befehl Trigger auslöst, wird jeder Trigger in seinem eigenen verschachtelten Bereich ausgeführt.

Somit sind die Unterschiede zwischen den drei Identitätsabrufmethoden wie folgt:

@@identity Gibt den letzten Identitätswert zurück, der in this session aber any scope generiert wurde.

scope_identity() gibt den letzten Identitätswert zurück, der in this session und this scope generiert wurde.

ident_current() gibt den letzten Identitätswert zurück, der für eine bestimmte Tabelle in den Bereichen any session und any generiert wurde.

14
Hemant Sakta

Bereich bezeichnet den Codekontext, der die INSERT -Anweisung SCOPE_IDENTITY() ausführt, im Gegensatz zum globalen Bereich von @@IDENTITY.

CREATE TABLE Foo(
  ID INT IDENTITY(1,1),
  Dummy VARCHAR(100)
)

CREATE TABLE FooLog(
  ID INT IDENTITY(2,2),
  LogText VARCHAR(100)
)
go
CREATE TRIGGER InsertFoo ON Foo AFTER INSERT AS
BEGIN
  INSERT INTO FooLog (LogText) VALUES ('inserted Foo')
  INSERT INTO FooLog (LogText) SELECT Dummy FROM inserted
END

INSERT INTO Foo (Dummy) VALUES ('x')
SELECT SCOPE_IDENTITY(), @@IDENTITY 

Gibt unterschiedliche Ergebnisse.

12
devio

Aufgrund des von @David Freitas erwähnten Fehlers und der Inkompatibilität mit der 2012 eingeführten neuen Sequence-Funktion würde ich empfehlen, sich von allen dreien fernzuhalten. Stattdessen können Sie die OUTPUT-Klausel verwenden, um den eingefügten Identitätswert abzurufen. Der andere Vorteil ist, dass OUTPUT auch dann funktioniert, wenn Sie mehr als eine Zeile eingefügt haben.

Einzelheiten und Beispiele finden Sie hier: Identitätskrise

7
Sebastian Meine

Um das Problem mit @@Identity Zu klären:

Wenn Sie zum Beispiel eine Tabelle einfügen und diese Tabelle Trigger hat, die Inserts ausführen, gibt @@Identity Die ID des Inserts im Trigger zurück (ein log_id Oder so), während scope_identity() gibt die ID aus der Einfügung in die Originaltabelle zurück.

Wenn Sie also keine Trigger haben, geben scope_identity() und @@identity Denselben Wert zurück. Wenn Sie Trigger haben, müssen Sie sich überlegen, welchen Wert Sie möchten.

6
Jonas Lincoln

Hier ist eine weitere gute Erklärung von dem Buch :

Angenommen, Sie haben eine gespeicherte Prozedur P1 mit drei Anweisungen für den Unterschied zwischen SCOPE_IDENTITY und @@ IDENTITY:
- Ein INSERT, das einen neuen Identitätswert generiert
- Ein Aufruf einer gespeicherten Prozedur P2 mit einer INSERT-Anweisung, die einen neuen Identitätswert generiert
- Eine Anweisung, die die Funktionen SCOPE_IDENTITY und @@ IDENTITY abfragt. Die Funktion SCOPE_IDENTITY gibt den von P1 generierten Wert (gleiche Sitzung und Bereich) zurück. Die Funktion @@ IDENTITY gibt den von P2 generierten Wert zurück (gleiche Sitzung, unabhängig vom Bereich).

3
Dmitriy Dokshin

Scope Identity: Identität des letzten in der ausgeführten gespeicherten Prozedur hinzugefügten Datensatzes.

@@Identity: Identität des letzten im Abfragebatch hinzugefügten Datensatzes oder als Ergebnis der Abfrage, z. Bei einer Prozedur, die ein Einfügen ausführt, wird beim Auslösen eines Auslösers, der dann einen Datensatz einfügt, die Identität des eingefügten Datensatzes vom Auslöser zurückgegeben.

IdentCurrent: Die letzte für die Tabelle zugewiesene Identität.

3
Andrew