Tan*_*ven 24 sql sql-server sql-order-by sql-server-2012
我们正在从SQL Server 2008迁移到SQL Server 2012,并立即注意到我们所有的表值函数都不再以正确排序的顺序提供临时表内容.
码:
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**
Run Code Online (Sandbox Code Playgroud)
在SQL Server 2008中,此函数返回按名称排序的客户.在SQL Server 2012中,它返回未排序的表.在"排序依据" 2012年SQL被忽略.
我们是否必须重新编写所有函数以包含a sort_id
,然后在主应用程序中调用它们时对它们进行排序或是否有一个简单的修复?
Mar*_*ith 34
你的原始方法有两个问题.
ORDER BY
的INSERT ... SELECT ... ORDER BY
将是该行实际上是插入的顺序.SELECT
不会ORDER BY
以任何特定顺序返回行,例如插入顺序.在2012年,看起来好像行为已经改变了第1项.它现在通常忽略了作为一个来源ORDER BY
的SELECT
声明INSERT
DECLARE @T TABLE(number int)
INSERT INTO @T
SELECT number
FROM master..spt_values
ORDER BY name
Run Code Online (Sandbox Code Playgroud)
更改行为的原因是,在以前的版本中,SQL Server生成了一个在执行与SET ROWCOUNT 0
(off)和之间共享的计划SET ROWCOUNT N
.排序运算符仅用于确保计划由具有非零ROWCOUNT
集的会话运行时的正确语义.TOP
左边的操作员是a ROWCOUNT TOP
.
SQL Server 2012现在为这两种情况生成单独的计划,因此无需将这些ROWCOUNT 0
计划添加到计划的版本中.
如果SELECT
具有明确TOP
定义的(TOP 100 PERCENT
但不是)但是仍然不能保证行的实际插入顺序,则计划中的排序可能仍会出现在2012年的计划中,然后计划可能在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
Run Code Online (Sandbox Code Playgroud)
但是你仍然需要sort_id
在你选择的查询中进行排序,因为没有这个没有保证的顺序(也许这种sort_id
方法在用于排序的原始列没有被复制到表变量的情况下可能是有用的)