Sql 插入具有标识的多行时是否保证顺序?

Sql 插入具有标识的多行时是否保证顺序?,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,在表中插入多行时,是否可以保证它们按照我指定的顺序进行?例如,采取以下措施: DECLARE @blah TABLE ( ID INT IDENTITY(1, 1), Name VARCHAR(100) NOT NULL ); INSERT INTO @blah (Name) VALUES('Timmy'), ('Jonny'), ('Sally'); SELECT * FROM @blah 是否可以保证Sally的主键高于Timmy?您最好的两个选

在表中插入多行时,是否可以保证它们按照我指定的顺序进行?例如,采取以下措施:

DECLARE @blah TABLE
(
    ID INT IDENTITY(1, 1),
    Name VARCHAR(100) NOT NULL
);

INSERT INTO @blah (Name)
    VALUES('Timmy'),
    ('Jonny'),
    ('Sally');

SELECT * FROM @blah

是否可以保证Sally的主键高于Timmy?

您最好的两个选项是:

单独处理行-插入父行,获取ID,然后插入子行,然后插入下一个父行,等等

或者,假设数据在现实世界中有一个实际的标识符(例如,电子邮件地址、SSN等),那么在插入到子表中时,您可以使用该标识符连接回父表。

以前曾询问过类似的问题

您可以在
INSERT
中指定
顺序

如果这样做,则生成
标识
值的顺序将保证与
插入
中指定的
顺序匹配

以您的例子:

DECLARE @blah TABLE
(
    ID INT IDENTITY(1, 1) NOT NULL,
    Name VARCHAR(100) NOT NULL
);

INSERT INTO @blah (Name)
SELECT T.Name
FROM
    (
        VALUES
        ('Timmy'),
        ('Jonny'),
        ('Sally')
    ) AS T(Name)
ORDER BY T.Name;

SELECT
    T.ID
    ,T.Name
FROM @blah AS T
ORDER BY T.ID;
结果是:

+----+-------+
| ID | Name  |
+----+-------+
|  1 | Jonny |
|  2 | Sally |
|  3 | Timmy |
+----+-------+
也就是说,
Name
已被排序,并且已根据此顺序生成ID。可以保证乔尼的身份证最低,蒂米的身份证最高,莎莉的身份证在他们之间。生成的ID值之间可能存在间隙,但它们的相对顺序是有保证的

如果在
INSERT
中未指定
orderby
,则生成的
IDENTITY
ID可以以不同的顺序生成

请注意,即使使用
INSERT
中的
orderby
,也无法保证表中行的实际物理顺序,唯一的保证是生成的ID

乌马钱达尔·贾亚钱德兰女士在一个问题中说:

唯一的保证是,标识值将基于 关于ORDER BY条款。但这并不能保证交易的顺序 将行插入表中

他还提供了一个链接,SQL Server引擎团队的Conor Cunningham说:

  • 使用SELECT with ORDER BY填充行的INSERT查询可以保证标识值的计算方式,但不能保证其计算顺序 将插入行
  • 在那篇文章的评论中有一个指向微软知识库文章的链接:,这篇文章更详细地解释了这一点。它说:

    如果希望按顺序分配
    标识
    值 在
    orderby
    子句中的排序之后,创建一个 包含具有
    标识的列
    属性,然后运行
    插入。。。选择。。。ORDER BY
    查询以填充此表


    我将这篇KB文章视为官方文件,并考虑这一行为的保证。

    既然你在使用身份,为什么这很重要?您有效地使用了一个随机(尽管是可预测的)数字。我很确定它们将按指定的顺序插入,但这真的重要吗?是的,重要。这是我能想到的问题的最简单形式,但在“现实世界”场景中,我输出身份,并在其他地方使用它们。你永远不应该使用这样的身份列。如果您需要保证数字遵循某种可预测的序列,那么您应该明确地生成该序列。您不是在查找标识列,而是在数据库中查找具有某种业务意义的内容,您应该定义该内容并提供该内容。如果要在其他地方使用指定的标识值,则应使用OUTPUT子句。这样,您可以100%确定输入值中的哪个标识值与哪个行匹配。您似乎依赖多个表中标识属性的值来保持同步。这个很脆。让身份做它自己的事情并利用它的价值。试图估计它可能是什么必然会导致重大问题。这是保证还是当前的行为?在这里,我不会将Umachandar Jayachandran的声明视为官方产品文档。在任何情况下,标识值都可能存在缺口,因此无法恢复。不确定他是否需要。可能是。@usr,这篇文章有一个指向微软知识库文章的链接,这篇文章详细解释了它。所以,是的,我将它视为官方文档,并考虑这种行为的保证。@是的,生成的身份值可能有漏洞,但问题是:“有没有保证莎丽将具有比蒂米更高的主键?”答案是:“是的,如果您在<代码>插入< <代码> >中使用适当的<代码>命令> <代码>,当你回答“不”时,@TomH,我没有问他们是否是连续的。我问订单是否有保证。(“有没有保证Sally的主键会比Timmy的主键高?”)我这样说是因为我知道不能保证不会有空格。