如何提取 SQL Server 中最后插入的行?

use*_*976 8 sql-server insert t-sql identity

执行insert语句时,在表中插入了一行或多行,SQL Server有没有办法提取最后插入的行?

Aar*_*and 17

根据定义,表是一组无序的行(请参阅此处的 #3)。除非您在与插入相同的批次中这样做,否则无法询问 SQL Server 最后插入哪一行。例如,如果你的表有一个IDENTITY列,你可以使用SCOPE_IDENTITY()(永远不要使用@@IDENTITY,因为如果你有或将要向源表添加触发器,这可能是不可靠的):

INSERT dbo.table(column) SELECT 1;
SELECT SCOPE_IDENTITY();
Run Code Online (Sandbox Code Playgroud)

更一般地,您可以使用OUTPUT不依赖于IDENTITY列的子句(但如果没有 PK,仍然很难确定子句标识了哪些行):

INSERT dbo.table(column) OUTPUT inserted.* SELECT 1;
Run Code Online (Sandbox Code Playgroud)

如果您不是在谈论同一批次,那么识别最后插入的行的唯一真正方法是使用记录插入时间戳的日期/时间列。否则就像你把一袋弹珠倒在地板上,然后让某人进入房间并确定最后落到地板上的是哪个。

您可能会受到诱惑甚至被建议使用该IDENT_CURRENT()功能,但我在这里解释了为什么这也不可靠。

您可以添加一列来跟踪此进展:

ALTER TABLE dbo.table ADD DateInserted DEFAULT CURRENT_TIMESTAMP;
Run Code Online (Sandbox Code Playgroud)

现在您可以简单地找到插入的最后一行:

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

(如果你不想要平局,你可以在 中添加一个打破平局的列ORDER BY,或者如果你不关心你得到了哪些并列行,你可以简单地更改RANK()ROW_NUMBER()。)

您可能会假设插入的最后一行是最高的标识值,但情况并非一定如此。身份可以重新播种,也可以使用 覆盖SET IDENTITY_INSERT ON;