Wie extrahiere ich die zuletzt eingefügte Zeile in SQL Server?

8

Gibt es eine Möglichkeit, die zuletzt eingefügte Zeile in SQL Server zu extrahieren, wenn eine Einfügeanweisung ausgeführt wird und eine oder mehrere Zeilen in die Tabelle eingefügt werden?

user2493976
quelle
In meinem Fall hatte ich eine eindeutige ID-Spalte, die eine einfache automatische Inkrementierung von INT war, daher half dieser Artikel .
Todd

Antworten:

17

Per Definition ist eine Tabelle eine ungeordnete Reihe von Zeilen ( siehe Nr. 3 hier ). Es gibt keine Möglichkeit, SQL Server zu fragen, welche Zeile zuletzt eingefügt wurde, es sei denn, Sie tun dies im selben Stapel wie die Einfügung. Wenn Ihre Tabelle beispielsweise eine IDENTITYSpalte enthält, können Sie Folgendes verwenden SCOPE_IDENTITY()(niemals verwenden @@IDENTITY, da dies unzuverlässig sein kann, wenn Sie der Quelltabelle Trigger hinzugefügt haben oder jemals hinzufügen werden):

INSERT dbo.table(column) SELECT 1;
SELECT SCOPE_IDENTITY();

Im Allgemeinen können Sie die OUTPUTKlausel verwenden, die nicht auf einer IDENTITYSpalte basiert (es jedoch schwierig macht zu identifizieren, welche Zeile (n) die Klausel identifiziert, wenn keine PK vorhanden ist):

INSERT dbo.table(column) OUTPUT inserted.* SELECT 1;

Wenn Sie nicht über denselben Stapel sprechen, können Sie die zuletzt eingefügte Zeile nur anhand einer Datums- / Zeitspalte identifizieren, in der der Zeitstempel des Einfügens aufgezeichnet wird. Ansonsten ist es so, als hätten Sie eine Tüte Murmeln auf dem Boden geleert und dann jemanden gebeten, den Raum zu betreten und herauszufinden, welcher zuletzt auf den Boden gefallen ist.

Sie könnten versucht sein oder sogar geraten, die IDENT_CURRENT()Funktion zu verwenden, aber ich erkläre hier, warum dies auch unzuverlässig ist.

Sie können eine Spalte hinzufügen, um dies in Zukunft zu verfolgen:

ALTER TABLE dbo.table ADD DateInserted DEFAULT CURRENT_TIMESTAMP;

Jetzt können Sie die zuletzt eingefügten Zeilen finden, indem Sie einfach:

;WITH x AS (SELECT *, r = RANK() OVER (ORDER BY DateInserted DESC)
   FROM dbo.table)
SELECT * FROM x WHERE r = 1;

(Wenn Sie keine Bindungen möchten, können Sie der Spalte eine Spalte hinzufügen ORDER BY, oder Sie können einfach zu wechseln RANK(), ROW_NUMBER()wenn es Ihnen egal ist, welche der gebundenen Zeilen Sie erhalten.)

Sie können davon ausgehen, dass die zuletzt eingefügte Zeile der höchste Identitätswert ist, dies ist jedoch nicht unbedingt der Fall. Die Identität kann neu gesetzt und mit überschrieben werden SET IDENTITY_INSERT ON;.

Aaron Bertrand
quelle