2012-07-11 94 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); 

阿尔贝托