窗口函数子句中来自SQL Server的奇怪不一致的行为?

在提出另一个问题时,我发现SQL Server(2005年和2008年都会发生)在处理窗口函数子句中的CASE语句时似乎有奇怪的不一致行为。 以下代码给出了一个错误:

declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0

select  row_number() over (order by
            case when 1=1 then SortColumn end asc,
            case when 1=0 then SortColumn end desc) RowNumber
,       *
from    @t

错误是窗口函数不支持作为ORDER BY子句表达式的常量。 我认为这是因为case语句可能评估为NULL ,这是一个常量。 也可以预料,这段代码给出了同样的错误:

declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0

select  row_number() over (order by
            NULL asc,
            NULL desc) RowNumber
,       *
from    @t

......大概是出于同样的原因。 但是,此代码不会给出错误:

declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0

select  row_number() over (order by
            case when @asc=1 then SortColumn end asc,
            case when @asc=0 then SortColumn end desc) RowNumber
,       *
from    @t

唯一与第一个代码块不同的地方在于我已经将case语句的条件操作数之一移动到变量@asc 。 这现在工作正常。 为什么? case语句仍然可以评估为NULL ,这是一个常量,所以它不应该工作......但它确实如此。 某种程度上这是否一致,还是微软提出的特殊情况?

所有这些behvaiour可以通过玩这个查询来检查。


更新:这个限制不仅适用于OVER子句(虽然它们会给出不同的错误) - 它适用于自SQL Server 2005以来的所有ORDER BY子句。下面是一个查询,该查询还显示了使用常规SELECTORDER BY条款。


联机丛书指出“一个排序列可以包含一个表达式,但是当数据库处于SQL Server(90)兼容模式时,表达式不能解析为一个常量”。 但它没有定义“常量”。

从思考它和一些实验中,似乎很清楚,这意味着一个表达式,它可以在编译时成功计算文字常数值。

/*Works - Constant at run time but SQL Server doesn't do variable sniffing*/
DECLARE @Foo int
SELECT ROW_NUMBER() OVER (ORDER BY @Foo) 
FROM master..spt_values 

/*Works - Constant folding not done for divide by zero*/
SELECT ROW_NUMBER() OVER (ORDER BY $/0) 
FROM master..spt_values 

/*Fails - Windowed functions do not support 
   constants as ORDER BY clause expressions.*/
SELECT ROW_NUMBER() OVER (ORDER BY $/1) 
FROM master..spt_values 

你的第一个例子中的评估将永远不会改变。

你正在比较一个常数和一个恒定常数。

1=1将始终为TRUE
1=0将始终为FALSE

链接地址: http://www.djcxy.com/p/54611.html

上一篇: Curious inconsistent behaviour from SQL Server in windowed function clauses?

下一篇: balancing in parallel processing application