【问题标题】:When using OUTPUT in an insert statement, if you specify the order by in the select does it honor the order specified in the select?在插入语句中使用 OUTPUT 时,如果您在 select 中指定 order by,它是否遵守 select 中指定的顺序?
【发布时间】:2019-06-24 12:17:44
【问题描述】:

我将数据插入到两个表中。在每个插入中,都有一个到 #temp 表的 OUTPUT,每个表都有一个标识列。为插入生成数据的选择对于每个插入具有相同的顺序。稍后,我通过 Identity 列加入两个 #temp 表。我所期望的是,在插入时,标识列号将按照双方指定的顺序排列。每隔一段时间,这些数字似乎不匹配,我唯一能想到的是,在将 OUTPUT 数据写入临时表时,OUTPUT 可能并不总是遵守 select 语句中的顺序。

CREATE TABLE #TempTable
(
    RowNumber Integer IDENTITY (1,1) NOT NULL,
    TableID Integer

    CONSTRAINT PK_TableID PRIMARY KEY NONCLUSTERED (RowNumber)
)

INSERT INTO Table
    (column1,column2,column3,etc)
OUTPUT   
    INSERTED.ID
INTO #TempTable
    (ID)  
SELECT
    column1,column2,column3,etc
FROM
Other table
ORDER BY 
    SourceFlag,
    StoreID,
    storenumber,
    EstablishDate,
    TableID

我希望这些语句会以相同的顺序从 1 到 25 在两个语句中插入例如 25 行。然后我应该能够根据行号 1 = 1、25= 25 等加入。为了得到匹配的数据。我认为正在发生的事情是顺序被弄乱了,所以第一个插入的第 1 行确实匹配第二个插入的第 14 行,所以当我后来加入 1 对 1 时,我得到的数据不匹配。

【问题讨论】:

  • 您的情况有点不清楚,因为上面的INSERT 应该不起作用。 #TempTable 没有ID,而如果#TempTable 有并且它是一个标识,则向其插入值将不起作用,除非您使用IDENTITY_INSERT,这似乎没有必要。您可以使用ROW_NUMBER() OVER (ORDER BY...) 生成明确的顺序,而不是依赖于生成身份的任何顺序。
  • 根据docs, "INSERT 查询使用SELECTORDER BY 来填充行保证了标识值的计算方式但不是插入行的顺序”(强调我的)。请注意,这仅指插入到的表的标识,而不是OUTPUT 子句中引用的任何表——您从INSERTED.ID 返回的内容是确定性的,但作为@987654334 的结果生成的标识值@ 不会是。但是,根据我之前的评论,你不应该需要这些。

标签: sql sql-server output


【解决方案1】:

显然,it doesn't:

但是,SQL Server 不保证行的顺序 使用 OUTPUT 子句由 DML 语句处理和返回。

您需要识别数据中的自然键,然后引用它以将新插入的行与OUTPUT 结果集匹配。

或者,您可以将INSERT 替换为MERGE;在这种情况下,您将能够在 OUTPUT 子句中为您的记录捕获新创建的 identity 值。

【讨论】:

    猜你喜欢
    • 2019-01-29
    • 2016-11-15
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 2012-04-21
    • 2012-01-26
    • 2014-11-29
    相关资源
    最近更新 更多