【问题标题】:Order guarantee for identity assignment in multi-row insert in SQL ServerSQL Server多行插入中标识分配的顺序保证
【发布时间】:2012-06-27 07:00:41
【问题描述】:

使用表值构造函数 (http://msdn.microsoft.com/en-us/library/dd776382(v=sql.100).aspx) 插入多行时,是否填充了任何标识列的顺序保证与 TVC 中的行匹配?

例如

CREATE TABLE A (a int identity(1, 1), b int)

INSERT INTO A(b) VALUES (1), (2)

引擎保证 a 的值与 b 的分配顺序相同,即在这种情况下,它们匹配 a=1、b=1 和 a=2、b=2。

【问题讨论】:

    标签: sql sql-server sql-server-2008


    【解决方案1】:

    捎带我上面的评论,并且知道插入/选择+排序的行为将保证生成身份顺序(#4:from this blog

    假设您希望身份生成基于类别 ID,您可以按以下方式使用表值构造函数来实现您的目标(不确定这是否满足您的其他约束)。

    insert into thetable(CategoryId, CategoryName)
    select *
    from
      (values
        (101, 'Bikes'),
        (103, 'Clothes'),
        (102, 'Accessories')
      ) AS Category(CategoryID, CategoryName)
    order by CategoryId
    

    【讨论】:

    • 因此使用 OP 的示例,如果 OP 想要保证每行中 ab 之间的匹配,他们可以像 INSERT INTO A(b) SELECT b FROM (VALUES (1), (2)) AS v (b) ORDER BY b 一样。你说的是这个吗?
    • 注意你只能通过order by保证获取行的顺序。如果您从一个选择中插入(没有order by),则无法保证从一开始就如何插入这些行(以任何特定顺序)。使用上面示例中的表达式不会产生保证,除非您明确包含一些列以按顺序使用并使用有序值。在上面的示例中,您将得到 101,102 和 103 作为order by 命令
    【解决方案2】:

    这取决于您是否一次性插入记录。例如插入后,如果删除 a=2 的记录,然后再次重新插入值 b=2 ,则标识列的值将是 max(a)+1

    演示

     DECLARE @Sample TABLE
     (a int identity(1, 1), b int)
    
     Insert into @Sample values (1),(2)
    
    a   b
    1   1
    2   2
    
     Delete from @Sample where a=2
    
     Insert into @Sample values (2)
     Select * from @Sample
    
     a  b
     1  1
     3  2
    

    【讨论】:

    • 我是一次性插入,我想知道订单是否有保证。比较 blogs.msdn.com/b/sqltips/archive/2005/07/20/441053.aspx 项目 4,它有插件的订单保证。在我上面插入之后,我想知道订单是否可能是 a=1, b=2 和 a=2, b=1
    • 组合将始终保持不变。文档说,当您使用 Insert into ...从插入的行中选择时,插入的顺序可能不正确。数据以正确的值插入,但不是以正确的顺序。例如,如果您插入 b=1 和 b=2。检索到的数据将是 a=2 b=2 和 a=1 b=1。此问题已从 sql server 2008 解决
    • 我知道 TVC 是 2008 年的一项新功能,但不确定您指的是什么问题。如果您可以向我指出一些文档或其他任何表明这是保证订单的内容,请将其标记为正确答案。谢谢。
    • 我最近也一直在寻找这个信息,但找不到。 sql-92 标准(我们知道 t-sql 如何 100% 遵守这一点:P)要求表值构造函数组合功能类似于 union all。 Union all 不保证顺序,所以我现在倾向于相信它不能保证。
    • 演示与提问无关。
    猜你喜欢
    • 2016-04-09
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    相关资源
    最近更新 更多