Sql-Server

可以參與 SET 操作的局部變數的最大數量是多少?

  • December 31, 2017

我有一個包含業務邏輯的儲存過程。在它裡面我有大約 1609 個變數(不要問我為什麼,這就是引擎的工作原理)。我嘗試將SET一個變數連接到所有其他變數的連接值。結果在創建過程中出現錯誤:

消息 8631,級別 17,狀態 1,過程 XXX,行 YYY 內部錯誤:已達到伺服器堆棧限制。請在您的查詢中尋找潛在的深層嵌套,並嘗試簡化它。

我發現錯誤是由於我需要在SET操作中使用的變數數量造成的。我可以通過將其分成兩部分來執行任務。

我的問題是這方面有一些限制嗎?我查了,但沒有找到。

我們檢查了此 KB中描述的錯誤,但這不是我們的情況。我們在程式碼中不使用任何CASE表達式。我們使用該臨時變數來準備必須使用 CLR 函式替換的值列表。我們將 SQL Server 更新到 SP3 CU6(最新),但我們仍然遇到錯誤。

消息 8631,級別 17,狀態 1,第 xxx 行

內部錯誤:已達到伺服器堆棧限制。

請在您的查詢中尋找潛在的深層嵌套,並嘗試簡化它。

由於 SQL Server 解析和綁定此類語句的方式(作為兩個輸入串聯的嵌套列表),長SET或變數賦值串聯列表會發生此錯誤。SELECT

例如,SET @V = @W + @X + @Y + @Z被綁定到如下形式的樹中:

ScaOp_Arithmetic x_aopAdd
   ScaOp_Arithmetic x_aopAdd
       ScaOp_Arithmetic x_aopAdd
           ScaOp_Identifier @W 
           ScaOp_Identifier @X 
       ScaOp_Identifier @Y 
   ScaOp_Identifier @Z 

前兩個元素之後的每個連接元素都會在此表示中產生額外的嵌套級別。

SQL Server 可用的堆棧空間量決定了此嵌套的最終限制。當超出限制時,會在內部引發異常,最終導致如上所示的錯誤消息。拋出錯誤時的範例程序呼叫堆棧如下所示:

堆棧跟踪

複製品

DECLARE @SQL varchar(max);

SET @SQL = '
   DECLARE @S integer, @A integer = 1; 
   SET @S = @A'; -- Change to SELECT if you like

SET @SQL += REPLICATE(CONVERT(varchar(max), ' + @A'), 3410) +';'; -- Change the number 3410

-- SET @S = @A + @A + @A...
EXECUTE (@SQL);

由於內部處理多個串聯的方式,這是一個基本限制。它同樣影響SETSELECT變數賦值語句。

解決方法是限制在單個語句中執行的連接數。這通常也會更有效,因為編譯深度查詢樹是資源密集型的。

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