2012-07-11 93 views
2

我在SQL Server 2005中編寫了一個存儲過程,該存儲過程聲明瞭一個名爲foo的CTE(公用表表達式)。本地變量的MAXRECURSION值

foo以遞歸方式調用自身,但當其中一個SP的參數(@bar)爲空時會無限循環。

要停止這個無限循環,我一直在試圖使用選項MAXRECURSION

  • @bar爲空,設置MAXRECURSION爲1;
  • @bar不爲空時,將MAXRECURSION設置爲0(無限制)。

所以我宣佈了一個局部變量@maxrec,取決於@bar是否爲null,取值爲1或0。

DECLARE @maxrec INT; 
SET @maxrec = 0; 
if (@dim_course_categories is null) 
begin 
    SET @maxrec = 1; 
end 

;WITH foo AS (
    ... 
) 

SELECT * FROM foo 
OPTION (MAXRECURSION @maxrec) 

當我解析的代碼,我得到以下錯誤: Incorrect syntax near '@maxrec'.,它指的是線OPTION (MAXRECURSION @localvar)

那麼我做錯了什麼?禁止在OPTION子句中使用局部變量嗎?

+3

沒有什麼是錯的,只是'MAXRECURSION'不接受一個變量,只能從0恆定到32767,很遺憾。請參閱[查詢提示](http://msdn.microsoft.com/zh-cn/library/ms181714.aspx)。 – 2012-07-11 02:24:06

+0

你可以發佈更多的CTE,所以我們可以看到爲什麼它永遠循環?可能有一種更優雅的方式來處理'@bar = NULL'。或者簡單地用'if'來執行兩個查詢中的一個,一個用完整的CTE,另一個用只有最初的'select'但不用'union'的查詢。 – HABO 2012-07-11 02:55:54

+0

是的,這正是我最終做的事情(使用一個大的IF ... ELSE語句)。 SP的代碼長度差不多是它的兩倍,但它比紅色代碼更具可讀性。 – Axel 2012-07-11 04:07:45

回答

3

一種選擇將是該語句完成之前,以構建查詢,然後用EXEC sp_executesql

DECLARE @Query NVARCHAR(MAX) 

SET @Query = N' 
    ;WITH foo AS (
     ... 
    ) 

    SELECT * FROM foo 
    OPTION (MAXRECURSION ' + CAST(@maxrec AS NVARCHAR) + ');' 

EXEC sp_executesql @Query 

在一個側面說明執行它,如果達到MAXRECURSION值,查詢將無法正常結束時,它將拋出異常。這可能是你想要的,但只是知道它。

+0

即使它使代碼非常難讀,它的效果非常好!謝謝 – Axel 2012-07-11 03:04:10

0

另一種選擇是改變你的選擇

DECLARE @maxrec INT; 
SET @maxrec = 0; 
if (@dim_course_categories is null) 
    SET @maxrec = 1; 

;WITH foo AS (
    SELECT colonne 
    UNION ALL 
    SELECT colonne FROM foo 
    WHERE @maxrec = 0 
     AND (other_condition) 
) 

SELECT * FROM foo 
OPTION (MAXRECURSION 0); 

阿爾貝託