你原来的方法有两个问题。
- 在插入表时,永远不能保证
ORDER BY
onINSERT ... 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
的订购保证中的想法,可以保证在插入表时,这些表的分配顺序将按照,因此您也可以这样做IDENTITY
ORDER 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
方法在用于排序的原始列没有被复制到表变量中的情况下可能很有用)