Frage Der beste Weg, um die Identität der eingefügten Zeile zu erhalten?


Was ist der beste Weg zu bekommen? IDENTITY der eingefügten Zeile?

ich weiss Bescheid @@IDENTITY und IDENT_CURRENT und SCOPE_IDENTITY aber verstehen Sie nicht die Vor- und Nachteile für jeden.

Kann mir bitte jemand die Unterschiede erklären und wann sollte ich welche benutzen?


889
2017-09-03 21:32


Ursprung


Antworten:


  • @@IDENTITY Gibt den letzten Identitätswert zurück, der für alle Tabellen in der aktuellen Sitzung in allen Bereichen generiert wurde. Du musst hier vorsichtig sein, da es sich um Bereiche handelt. Sie könnten einen Wert von einem Auslöser anstelle Ihrer aktuellen Aussage erhalten.

  • SCOPE_IDENTITY() Gibt den letzten Identitätswert zurück, der für eine Tabelle in der aktuellen Sitzung und den aktuellen Bereich generiert wurde. Im Allgemeinen, was Sie verwenden möchten.

  • IDENT_CURRENT('tableName') Gibt den letzten Identitätswert zurück, der für eine bestimmte Tabelle in einer Sitzung und einem beliebigen Bereich generiert wurde. Auf diese Weise können Sie angeben, für welche Tabelle der Wert ausgewählt werden soll, falls die beiden oben genannten Werte nicht Ihren Anforderungen entsprechen (sehr selten). Ebenso wie @Guy Starbuck erwähnt, "Sie könnten dies verwenden, wenn Sie den aktuellen IDENTITY-Wert für eine Tabelle abrufen möchten, in die Sie keinen Datensatz eingefügt haben."

  • Das OUTPUT Klausel des INSERT Mit dieser Anweisung können Sie auf jede Zeile zugreifen, die über diese Anweisung eingefügt wurde. Da es auf die spezifische Aussage beschränkt ist, ist es direkter als die anderen oben genannten Funktionen. Es ist jedoch ein wenig ausführlicher (Sie müssen in eine Tabellenvariable / temporäre Tabelle einfügen und diese dann abfragen), und sie liefert Ergebnisse auch in einem Fehlerszenario, in dem die Anweisung zurückgesetzt wird. Wenn Ihre Abfrage einen parallelen Ausführungsplan verwendet, ist dies der Fall nur garantierte Methode um die Identität zu erhalten (kurz davor, die Parallelität auszuschalten). Es wird jedoch ausgeführt Vor Trigger und kann nicht verwendet werden, um Trigger-generierte Werte zurückzugeben.


1171
2017-09-03 21:38



Ich glaube, die sicherste und genaueste Methode zum Abrufen der eingefügten ID wäre die Verwendung der Ausgabeklausel.

zum Beispiel (aus dem Folgenden MSDN Artikel)

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

150
2018-05-20 14:43



Ich sage das Gleiche wie die anderen Jungs, also sind alle in Ordnung, ich versuche nur, es klarer zu machen.

@@IDENTITY Gibt die ID des letzten Objekts zurück, das von der Verbindung Ihres Clients mit der Datenbank eingefügt wurde.
Meistens funktioniert das gut, aber manchmal wird ein Trigger ausgelöst und eine neue Zeile eingefügt, von der Sie nichts wissen, und Sie erhalten die ID aus dieser neuen Zeile statt der gewünschten Zeile

SCOPE_IDENTITY() behebt dieses Problem. Es gibt die ID der letzten Sache zurück du hast eingefügt im SQL-Code du hast geschickt zur Datenbank. Wenn Trigger zusätzliche Zeilen erstellen, verursachen sie nicht, dass der falsche Wert zurückgegeben wird. Hurra

IDENT_CURRENT Gibt die letzte ID zurück, die von jemand eingefügt wurde. Wenn eine andere App zufällig eine andere Zeile einfügt, erhältst du die ID dieser Zeile statt deiner.

Wenn du auf Nummer sicher gehen willst, benutze immer SCOPE_IDENTITY(). Wenn du bei dir bleibst @@IDENTITYund jemand beschließt, später einen Trigger hinzuzufügen, wird der ganze Code brechen.


94
2017-09-03 21:44



Der beste (also sicherste) Weg, um die Identität einer neu eingefügten Zeile zu erhalten, ist die Verwendung der output Klausel:

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

52
2018-04-29 07:22



Hinzufügen

SELECT CAST(scope_identity() AS int);

Bis zum Ende Ihrer Insert SQL-Anweisung, dann

NewId = command.ExecuteScalar()

wird es abrufen.


20
2018-03-30 18:25



MSDN

IDENTITY, SCOPE_IDENTITY und IDENT_CURRENT sind ähnliche Funktionen, da sie den letzten in die IDENTITY-Spalte einer Tabelle eingefügten Wert zurückgeben.

@@ IDENTITY und SCOPE_IDENTITY geben den letzten Identitätswert zurück, der in einer beliebigen Tabelle in der aktuellen Sitzung generiert wurde. SCOPE_IDENTITY gibt den Wert jedoch nur innerhalb des aktuellen Bereichs zurück. @@ IDENTITY ist nicht auf einen bestimmten Bereich beschränkt.

IDENT_CURRENT ist nicht nach Umfang und Sitzung begrenzt; Es ist auf eine bestimmte Tabelle beschränkt. IDENT_CURRENT gibt den Identitätswert zurück, der für eine bestimmte Tabelle in einer Sitzung und einem beliebigen Bereich generiert wurde. Weitere Informationen finden Sie unter IDENT_CURRENT.

  • IDENT_CURRENT ist eine Funktion, die eine Tabelle als Argument nimmt.
  • @@IDENTITÄT kann verwirrende Ergebnisse liefern, wenn Sie einen Trigger auf dem Tisch haben
  • SCOPE_IDENTITÄT ist die meiste Zeit dein Held.

12
2017-09-03 21:37



@@IDENTITÄT ist die letzte Identität, die mit der aktuellen SQL-Verbindung eingefügt wurde. Dies ist ein guter Wert, der von einer gespeicherten Insert-Prozedur zurückgegeben wird, wo Sie nur die Identität für Ihren neuen Datensatz eingeben müssen, und es ist nicht wichtig, ob später weitere Zeilen hinzugefügt wurden.

SCOPE_IDENTITÄT ist die letzte Identität, die mit der aktuellen SQL-Verbindung eingefügt wurde, und im aktuellen Gültigkeitsbereich - dh wenn eine zweite IDENTITY basierend auf einem Trigger nach der Einfügung eingefügt wurde, würde sie nicht in SCOPE_IDENTITY reflektiert, nur die von Ihnen durchgeführte Einfügung. Ehrlich gesagt, ich hatte nie einen Grund, dies zu benutzen.

IDENT_CURRENT (Tabellenname) ist die letzte Identität, die unabhängig von der Verbindung oder dem Bereich eingefügt wird. Sie können dies verwenden, wenn Sie den aktuellen IDENTITY-Wert für eine Tabelle abrufen möchten, in die Sie keinen Datensatz eingefügt haben.


11
2017-09-03 21:42



Wenn Sie Entity Framework verwenden, verwendet es intern das OUTPUT Technik, um den neu eingefügten ID-Wert zurückzugeben

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');

SELECT t.[TurboEncabulatorID ]
FROM @generated_keys AS g 
   JOIN dbo.TurboEncabulators AS t 
   ON g.Id = t.TurboEncabulatorID 
WHERE @@ROWCOUNT > 0

Die Ausgabeergebnisse werden in einer temporären Tabellenvariablen gespeichert, mit der Tabelle verbunden und geben den Zeilenwert aus der Tabelle zurück.

Anmerkung: Ich habe keine Ahnung, warum EF innerlich den ephemeren Tisch wieder an den realen Tisch anknüpfen würde (unter welchen Umständen würden die beiden nicht zusammenpassen).

Aber genau das macht EF.

Diese Technik (OUTPUT) ist nur auf SQL Server 2008 oder neuer verfügbar.


10
2017-11-04 15:05



IMMER Verwenden Sie scope_identity (), es besteht NIEMALS Bedarf an etwas anderem.


7
2017-10-09 20:35



Ich kann nicht mit anderen Versionen von SQL Server sprechen, aber im Jahr 2012 funktioniert die Ausgabe direkt gut. Sie müssen sich nicht mit einem temporären Tisch beschäftigen.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)

Diese Technik funktioniert übrigens auch beim Einfügen mehrerer Zeilen.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
    (...),
    (...),
    (...)

Ausgabe

ID
2
3
4

2
2018-06-06 16:58