【发布时间】:2019-05-16 02:50:41
【问题描述】:
SQL Server 是否保证将按照 INSERT 语句的 ORDER BY 子句指定的顺序为每一行调用 NewSequentialId()?
目标是在 C# 中获取一个对象列表,每个对象代表要插入到表中的一行,并以相当快的速度将它们插入到表中。
我想要做的是使用 SqlBulkCopy 将行插入到临时表中,然后将临时表中的行插入到使用 NewSequentialId() 的表中,然后以可以使用的方式检索新 ID按照与 C# 中的对象列表相同的顺序排序,以便可以将 ID 附加到 C# 中的每个对应对象。
我使用的是 SQL Server 2016,这是目标表:
CREATE TABLE dbo.MyTable
(
Id UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWSEQUENTIALID(),
SomeNonUniqueValue NVARCHAR(50) NOT NULL
)
首先我使用 SqlBulkCopy 将行插入到这个临时表中。 RowOrder 列包含应用程序中生成的整数。 RowOrder 是我需要返回生成的 ID 的顺序。在应用程序中,RowOrder 是列表中每个 C# 对象的索引。
CREATE TABLE #MyTableStaging
(
RowOrder INT NOT NULL,
SomeNonUniqueValue NVARCHAR(50) NOT NULL
)
然后我运行此 SQL 以从 #MyTableStaging 中获取行,将它们插入 MyTable 并检索插入的 ID。
DECLARE @MyTableOutput TABLE
(
Id UNIQUEIDENTIFIER NOT NULL
)
INSERT INTO dbo.MyTable (SomeNonUniqueValue)
OUTPUT Inserted.Id INTO @MyTableOutput(Id)
SELECT SomeNonUniqueValue
FROM #MyTableStaging
ORDER BY RowOrder
SELECT Id FROM @MyTableOutput ORDER BY Id
在我所有的测试中,这都有效。但是我最近发现,OUTPUT子句中指定的表中插入行的顺序并不总是和INSERT语句中ORDER BY指定的顺序相同(我发现这个是因为这个系统的原始设计是在#MyTableStaging 中使用身份,而不是按#MyTableStaging.Id 排序,而是按身份列排序)。
我知道 SQL Server 保证标识值按照 INSERT 语句的 ORDER BY 子句中指定的顺序生成(来自https://docs.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql?view=sql-server-2017#limitations-and-restrictions):
使用带有 ORDER BY 的 SELECT 来填充行的 INSERT 查询 保证身份值的计算方式,但不保证计算的顺序 行已插入。
【问题讨论】:
标签: sql sql-server newsequentialid