你原来的方法有两个问题。
- 在插入表时,永远不能保证
ORDER BYonINSERT ... SELECT ... ORDER BY将是实际插入行的顺序。
- 在从中选择时,SQL Server 不保证
SELECT没有 anORDER BY将返回任何特定顺序的行,例如插入顺序。
在 2012 年,第 1 项的行为似乎发生了变化。现在它通常ORDER BY忽略SELECT作为INSERT
DECLARE @T TABLE(number int)
INSERT INTO @T
SELECT number
FROM master..spt_values
ORDER BY name
2008年计划

2012年计划

行为改变的原因是,在以前的版本中,SQL Server 生成了一个计划,该计划在SET ROWCOUNT 0(off) 和SET ROWCOUNT N. 排序运算符只是为了确保正确的语义,以防计划由具有非零ROWCOUNT集的会话运行。它左边的TOP运算符是 a ROWCOUNT TOP。
SQL Server 2012 现在为这两种情况生成单独的计划,因此无需将这些添加到ROWCOUNT 0计划的版本中。
如果 2012 年的计划中仍会出现一个排序,如果SELECT有一个明确TOP定义(除了TOP 100 PERCENT),但这仍然不能保证行的实际插入顺序,那么在TOP N建立之后计划可能会有另一个排序以使行进入集群以索引顺序为例。
对于您问题中的示例,我只需调整调用代码以指定ORDER BY name它是否需要。
关于您在 SQL Server 中sort_id的订购保证中的想法,可以保证在插入表时,这些表的分配顺序将按照,因此您也可以这样做IDENTITYORDER BY
DECLARE @Customer TABLE (
Sort_Id INT IDENTITY PRIMARY KEY,
Customer_ID INT,
Name INT,
Expired BIT )
INSERT INTO @Customer
SELECT Customer_ID,
Name,
CASE
WHEN Expiry_Date < Getdate() THEN 1
WHEN Expired = 1 THEN 1
ELSE 0
END
FROM Customer
ORDER BY Name
但是您仍然需要sort_id在您的选择查询中进行排序,因为没有它就无法保证排序(也许这种sort_id方法在用于排序的原始列没有被复制到表变量中的情况下可能很有用)