Sql-Server

為什麼連結伺服器在 CASE 表達式中有 10 個分支的限制?

  • June 24, 2016

為什麼是這個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

產生這個結果?

錯誤消息:消息 8180,級別 16,狀態 1,行 1
無法準備語句。
Msg 125, Level 15, State 4, Line 1
Case 表達式只能嵌套到級別 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

顯然這裡沒有嵌套CASE表達式。

不在查詢文本中,沒有。但是解析器總是將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

本地查詢計劃

該查詢是本地的(無連結伺服器),計算標量定義了以下表達式:

嵌套 CASE 表達式

這在本地執行時很好,因為解析器看不到CASE超過 10 層深度的嵌套語句(儘管它確實將一個傳遞到本地查詢編譯的後期階段)。

但是,使用連結伺服器,生成的文本可能會被發送到遠端伺服器進行編譯。如果是這種情況,遠端解析器CASE會看到超過 10 層深度的嵌套語句,您會收到錯誤 8180。

另一個怪事。此內聯表值函式產生相同的錯誤

內聯函式就地擴展為原始查詢文本,因此連結伺服器會產生相同的錯誤也就不足為奇了。

但是類似的多語句 TVF 工作正常

類似,但不一樣。msTVF 涉及到 的隱式轉換varchar(max),這恰好阻止了將CASE表達式發送到遠端伺服器。因為CASE是在本地評估的,所以解析器永遠不會看到過度嵌套CASE並且沒有錯誤。如果您將表定義從更改為結果varchar(max)的隱式類型- 表達式將使用 msTVF 進行遠端處理,您將收到錯誤消息。CASE``varchar(2)

CASE最終,當遠端伺服器評估過度嵌套時會發生錯誤。如果CASE未在遠端查詢迭代器中評估 ,則不會產生錯誤。例如,以下包括一個CONVERT未遠端的,因此即使使用連結伺服器也不會發生錯誤:

SELECT CASE CONVERT(varchar(max), 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 SQL2K8R2.AdventureWorks.Production.Product AS p

CASE 未遠端

引用自:https://dba.stackexchange.com/questions/42837