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)
这可能存在效率问题,但我可以负担得起.