如何在Table-Valued-Function中为CTE设置maxrecursion选项

zal*_*ath 37 sql-server common-table-expression

我面临一个问题,即在TVF内声明CTE的maxrecursion选项

这是CTE(一个简单的日历):

DECLARE @DEBUT DATE = '1/1/11',   @FIN DATE = '1/10/11';

WITH CTE as(       
SELECT @debut as jour       
UNION ALL       
SELECT DATEADD(day, 1, jour)       
FROM   CTE      
WHERE  DATEADD(day, 1, jour) <= @fin)
SELECT jour FROM CTE option (maxrecursion 365)
Run Code Online (Sandbox Code Playgroud)

和TVF:

 CREATE FUNCTION [liste_jour]  
 (@debut date,@fin date)
 RETURNS TABLE
 AS     
 RETURN      
 (  
  WITH CTE as(       
  SELECT @debut as jour       
  UNION  ALL       
  SELECT DATEADD(day, 1, jour)       
  FROM   CTE      
  WHERE  DATEADD(day, 1, jour) <= @fin)
  SELECT jour FROM CTE
  --option (maxrecursion 365)
 )
Run Code Online (Sandbox Code Playgroud)

上面的TVF在没有maxrecursion选项的情况下运行正常但是该选项存在语法错误.解决办法是什么 ?

问候

Aak*_*shM 41

这个MSDN论坛主题我了解到

[] OPTION子句只能在语句级别使用

因此,您不能在视图定义或内联TVF内的查询表达式中使用它.在您的情况下使用它的唯一方法是创建没有OPTION子句的TVF 并在使用TVF的查询中指定它.我们有一个错误,它跟踪允许OPTION在任何查询表达式中使用子句的请求(例如,if exists()或CTE或视图).

并进一步

您无法在udf中更改该选项的默认值.您必须在引用udf的语句中执行此操作.

因此,在你的榜样,你必须指定OPTION,当你调用你的函数:

 CREATE FUNCTION [liste_jour]  
 (@debut date,@fin date)
 RETURNS TABLE
 AS     
 RETURN      
 (  
  WITH CTE as(       
  SELECT @debut as jour       
  UNION  ALL       
  SELECT DATEADD(day, 1, jour)       
  FROM   CTE      
  WHERE  DATEADD(day, 1, jour) <= @fin)
  SELECT jour FROM CTE -- no OPTION here
 )
Run Code Online (Sandbox Code Playgroud)

(后来)

SELECT * FROM [liste_jour] ( @from , @to ) OPTION ( MAXRECURSION 365 )
Run Code Online (Sandbox Code Playgroud)

请注意,你不能通过让第二个TVF执行上述操作来解决这个问题 - 如果你尝试,你会得到同样的错误."[该] OPTION子句只能在语句级别使用",这是最终的(现在).


Cri*_*ole 23

我知道,旧线程,但我需要相同的东西,只需使用多语句UDF处理它:

CREATE FUNCTION DatesInRange
(
    @DateFrom datetime,
    @DateTo datetime
)
RETURNS 
@ReturnVal TABLE 
(
    date datetime
)
AS
BEGIN

    with DateTable as (
        select dateFrom = @DateFrom

        union all

        select DateAdd(day, 1, df.dateFrom)
        from DateTable df
        where df.dateFrom < @DateTo
    )
    insert into @ReturnVal(date)

    select dateFrom

    from DateTable option (maxrecursion 32767)

    RETURN 
END
GO
Run Code Online (Sandbox Code Playgroud)

这可能存在效率问题,但我可以负担得起.

  • 这个答案可能会更好一些,因为在函数中不需要记住CTE(没有递归限制). (3认同)