sql-server – 为什么链接服务器在CASE表达式中有10个分支的限制?

为什么这个CASE表达式:
SELECT CASE column 
        WHEN 'a' THEN '1' 
        WHEN 'b' THEN '2' 
        ... c -> i
        WHEN 'j' THEN '10' 
        WHEN 'k' THEN '11'  
    END [col] 
FROM LinkedServer.database.dbo.table

产生这个结果?

Error message: Msg 8180,Level 16,State 1,Line 1
Statement(s) Could not be prepared.
Msg 125,Level 15,State 4,Line 1
Case expressions may only be nested to level 10.

显然,这里没有嵌套的CASE表达式,尽管有超过10个“分支”.

一个奇怪的是.此内联表值函数产生相同的错误

ALTER FUNCTION [dbo].[fn_MyFunction]
(   
     @var varchar(20)
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT CASE column 
            WHEN 'a' THEN '1' 
            WHEN 'b' THEN '2' 
            ... c -> i
            WHEN 'j' THEN '10' 
            WHEN 'k' THEN '11'  
        END [col] 
    FROM LinkedServer.database.dbo.table
)

但类似的多语句TVF工作正常:

ALTER FUNCTION [dbo].[fn_MyFunction]
(   
    @var varchar(20)
)
RETURNS @result TABLE 
(
    value varchar(max)
)
AS
BEGIN
    INSERT INTO @result
    SELECT CASE column 
            WHEN 'a' THEN '1' 
            WHEN 'b' THEN '2' 
            ... c -> i
            WHEN 'j' THEN '10' 
            WHEN 'k' THEN '11'  
        END [col] 
    FROM LinkedServer.database.dbo.table

RETURN;
END

解决方法

Clearly there isn’t a nested CASE expression here.

不在查询文本中,没有.但是解析器总是将CASE表达式扩展为嵌套形式:

SELECT CASE SUBSTRING(p.Name,1,1)
        WHEN 'a' THEN '1' 
        WHEN 'b' THEN '2' 
        WHEN 'c' THEN '3' 
        WHEN 'd' THEN '4' 
        WHEN 'e' THEN '5' 
        WHEN 'f' THEN '6' 
        WHEN 'g' THEN '7' 
        WHEN 'h' THEN '8' 
        WHEN 'i' THEN '9' 
        WHEN 'j' THEN '10' 
        WHEN 'k' THEN '11'  
    END
FROM AdventureWorks2012.Production.Product AS p

查询是本地的(没有链接服务器),Compute Scalar定义以下表达式:

这在本地执行时很好,因为解析器没有看到超过10个级别的嵌套CASE语句(尽管它确实将一个语句传递给本地查询编译的后续阶段).

但是,对于链接服务器,可以将生成的文本发送到远程服务器进行编译.如果是这种情况,远程解析器会看到超过10级深度的嵌套CASE语句,您将收到错误8180.

Another oddity. This inline table-valued function produces the same
error

内联函数就地扩展到原始查询文本中,因此链接服务器的相同错误结果也就不足为奇了.

But a similar multi-statement TVF works fine

相似,但不一样. msTVF涉及到varchar(max)的隐式转换,这恰好会阻止CASE表达式发送到远程服务器.因为CASE是在本地计算的,所以解析器永远不会看到过度嵌套的CASE并且没有错误.如果将表定义从varchar(max)更改为CASE结果的隐式类型 – varchar(2) – 表达式将使用msTVF进行远程处理,您将收到错误.

最终,当远程服务器评估过度嵌套的CASE时,会发生错误.如果未在远程查询迭代器中评估CASE,则不会产生错误.例如,以下包括未远程控制的CONVERT,因此即使使用链接服务器也不会发生错误

SELECT CASE CONVERT(varchar(max),SUBSTRING(p.Name,1))
        WHEN 'a' THEN '1' 
        WHEN 'b' THEN '2' 
        WHEN 'c' THEN '3' 
        WHEN 'd' THEN '4' 
        WHEN 'e' THEN '5' 
        WHEN 'f' THEN '6' 
        WHEN 'g' THEN '7' 
        WHEN 'h' THEN '8' 
        WHEN 'i' THEN '9' 
        WHEN 'j' THEN '10' 
        WHEN 'k' THEN '11'  
    END
FROM sql2K8R2.AdventureWorks.Production.Product AS p

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...