繁体   English   中英

表值函数 - 输出中忽略排序依据

[英]Table-Valued function - Order by is ignored in output

我们正在从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**

在SQL Server 2008中,此函数返回按名称排序的客户。 在SQL Server 2012中,它返回未排序的表。 SQL 2012中忽略了“order by”

我们是否必须重新编写所有函数以包含sort_id ,然后在主应用程序中调用它们时对它们进行排序还是有一个简单的修复方法?

你的原始方法有两个问题。

  1. 在插入到这是从来没有保证了表ORDER BYINSERT ... SELECT ... ORDER BY将是该行实际上是插入的顺序。
  2. 在从中进行选择时,SQL Server不保证没有ORDER BY SELECT将以任何特定顺序返回行,例如插入顺序。

在2012年,看起来行为已经相对于第1项发生了变化。它现在通常忽略SELECT语句上的ORDER BY ,它是INSERT的来源

DECLARE @T TABLE(number int)

INSERT INTO @T 
SELECT number
FROM master..spt_values
ORDER BY name

2008年计划

2008年计划

2012年计划

2012年计划

更改行为的原因是,在以前的版本中,SQL Server生成了一个在SET ROWCOUNT 0 (关闭)和SET ROWCOUNT N执行之间共享的计划。 排序运算符仅用于确保计划由具有非零ROWCOUNT集的会话运行时的正确语义。 左边的TOP运算符是ROWCOUNT TOP

SQL Server 2012现在为这两种情况生成单独的计划,因此无需将这些计划添加到计划的ROWCOUNT 0版本中。

如果SELECT具有明确的TOP定义(除了TOP 100 PERCENT ),那么排序可能仍会出现在2012年的计划中,但这仍然不能保证行的实际插入顺序,那么计划可能在TOP N之后有另一种排序例如,建立将行引入聚簇索引顺序。

对于您问题中的示例,我只需调整调用代码以指定ORDER BY name如果这是它所需要的。

关于来自SQL Server中的Ordering保证的 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方法在用于排序的原始列没有被复制到表变量的情况下可能是有用的)

将名为rowno的列添加到@Customer表

INSERT INTO @Customer

SELECT ROW_NUMBER()over(order by Name)rowno,Customer_ID, Name,
        CASE 
            WHEN Expiry_Date < GETDATE() then 1 
            WHEN Expired = 1 then 1 
            ELSE 0
            END
from Customer 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM