TSQL:避免内联函数中的 MAXRECURSION 限制

TSQL: avoid MAXRECURSION limit in a inline function

我有这个功能,给定初始日期和最终日期给出该范围内的相应 year/month:

CREATE FUNCTION [dbo].[fnYearMonth]
(
    @Initial Date,
    @Final Date 
)
RETURNS TABLE 
AS
RETURN
With dateRange(StatDate) as 
(
    select @Initial
    union all
    select dateadd(month, 1, StatDate)
    from dateRange 
    where dateadd(month, 1, StatDate) <= CAST(DATEADD(month,DATEDIFF(month,0,@Final)+1,0)-1 as Date)
)
select DATEPART(year, StatDate) AS MyYear, DATEPART(month, StatDate) AS MyMonth From dateRange where StatDate <= @Final

问题是 MAXRECURSION 的默认限制为 100 只能使可用日期范围最长为 8 年零 4 个月。那是不够的。

我尝试在使用此函数的函数中使用 "OPTION (MAXRECURSION 2000);",但没有成功,因为我在 WITH 语句中调用了此函数。

我现在唯一的解决办法就是把这个内联函数变成一个多语句函数并使用"OPTION (MAXRECURSION 2000);"。但出于性能原因,我宁愿避免使用此选项。 ¿还有其他选择吗?

感谢您的帮助。

尝试在底部添加 OPTION (MAXRECURSION 0) 或您希望的递归限制,如下所示..

您也可以使用 Calendar table 来避免所有这些给出您需要的输出的计算..

我的数据库中有一个日历 table,输出很容易计算,如下所示。我建议使用 table 而不是重复计算

select distinct month,year from dbo.calendar
where dAte>=getdate()-200 and date<=getdate()

如果您想使用递归选项,请添加 option(recursion) 如下所示

--这不适用于内联 table 值函数,请参见下面的演示 改变功能 [dbo].[fnYearMonth] ( @初始日期时间, @Final 日期时间 ) RETURNS TABLE 作为 RETURN 以日期范围为 ( select @Initial as statdate 联合所有 select dateadd(月, 1, StatDate) 从日期范围 其中 dateadd(month, 1, StatDate) <= CAST(DATEADD(month,DATEDIFF(month,0,@Final)+1,0)-1 as Datetime) ) select DATEPART(year, StatDate) AS MyYear, DATEPART(month, StatDate) AS MyMonth 从日期范围 其中 StatDate <= @Final 选项(最大递归 0);

更新: MAX 递归选项不适用于内联 table 值函数,它仅适用于多 table 值函数..

演示:

alter function 
dbo.getnum_test
(
@n int
)
returns table
as return
With cte as
(
select @n as n
union all
select @n+1
from cte
)

select * from cte
where  n<1000
option (maxrecursion 0)

alter function dbo.itvftest
(
@n int
)
returns
@numbers table
(
n int
)
as 
begin

With cte as
(
select @n as n
union all
select n+1
from cte
where cte.n<10000
)
Insert into @numbers
select * from cte
where  n<1000
option (maxrecursion 0)

return
end