SQL Server : the maximum recursion 100 has been exhausted before statement completion

14.8k views Asked by At

I have a query that is returning an error with the maximum levels of recursion exceeded.

I know how to fix this by adding OPTION (maxrecursion 0) to the query however, I have tried adding this at various places in the query and I cant find where to put it where the syntax is valid.

Can anyone give me any pointers as to where in my view the query hint needs to be inserted?

/****** Object:  View [dbo].[SiconCFMContractLinesDetailByDayView]    Script Date: 16/12/2016 12:02:35 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW [dbo].[SiconCFMContractLinesDetailByDayView]
AS
WITH dateRange as
(
SELECT      [Date] = DATEADD(dd, 1, DATEADD(dd, -1,[SiconCFMContractLinesOutstandingView].[NextDueDate])),
[Frequency] = [SiconCFMContractLinesOutstandingView].[FrequencyValue],
[EndDate] = DATEADD(yy,5, [SiconCFMContractLinesOutstandingView].[NextDueDate]),
[SiconCFMContractLinesOutstandingView].[SiconContractLineID]
FROM        [SiconCFMContractLinesOutstandingView]
WHERE       DATEADD(mm, [SiconCFMContractLinesOutstandingView].[FrequencyValue], [SiconCFMContractLinesOutstandingView].[NextDueDate]) < DATEADD(mm, [SiconCFMContractLinesOutstandingView].[FrequencyValue], DATEADD(yy,5, [SiconCFMContractLinesOutstandingView].[NextDueDate]))
UNION ALL
SELECT      DATEADD(mm, [Frequency], [Date]) [Date],
[Frequency],
[EndDate],
[SiconContractLineID]
FROM        dateRange
WHERE       DATEADD(mm, [Frequency], [Date]) < DATEADD(mm, [Frequency],[EndDate])

)

SELECT
(
SELECT CASE
WHEN dbo.fnSiconCFMGetSettingValue('UseAverageTimeToPay') = 'True'
THEN
CASE [SiconCFMSLCustomerAverageTimeToPayView].[AvgTimeToPayDateLastUpdated]
WHEN NULL THEN dbo.fnSiconCFMDateByPaymentTerms([SLCustomerAccount].[SYSPaymentTermsBasisID], [SLCustomerAccount].[PaymentTermsInDays], dateRange.[Date])
ELSE DATEADD([DD],[SiconCFMSLCustomerAverageTimeToPayView].[Days],dateRange.[Date])
END
ELSE dbo.fnSiconCFMDateByPaymentTerms([SLCustomerAccount].[SYSPaymentTermsBasisID], [SLCustomerAccount].[PaymentTermsInDays], dateRange.[Date])
END
)
AS [DueDate],
[StockItem].[Name] AS [Title],
[SiconCFMContractLinesOutstandingView].[Description] AS [Description],
[SiconCFMContractLinesOutstandingView].[UnitBillCoverPriceIncDisc] AS [Value],
[SiconCFMContractLinesOutstandingView].[SiconContractID],
[SiconCFMContractLinesOutstandingView].[SiconContractLineID],
[SiconCFMContractLinesOutstandingView].[SiconContractLineID] AS [ForecastDateForeignID],
'SiconContractLine' AS [ForecastDateSource],
(
SELECT
CASE WHEN EXISTS
(
SELECT [SiconCFMMemo].[SiconCFMMemoID]
FROM   [SiconCFMMemo]
WHERE  [SiconCFMMemo].[Deleted]=0
AND    [SiconCFMMemo].[IsActive]=1
AND    [SiconCFMMemo].[MemoSource]='SiconContractLine'
AND    [SiconCFMMemo].[MemoForeignID]=[SiconCFMContractLinesOutstandingView].[SiconContractLineID]
)
THEN 1
ELSE 0
END
) AS [HasMemos]
FROM            dateRange 
INNER JOIN      [SiconCFMContractLinesOutstandingView]
ON              dateRange.[SiconContractLineID]
=               [SiconCFMContractLinesOutstandingView].[siconContractLineID]
INNER JOIN      [StockItem]
ON              [StockItem].[ItemID]
=               [SiconCFMContractLinesOutstandingView].[ItemID]
INNER JOIN      [SLCustomerAccount]
ON              [SLCustomerAccount].[SLCustomerAccountID]
=               [SiconCFMContractLinesOutstandingView].[SLCustomerAccountID]
INNER JOIN      [SiconCFMSLCustomerAverageTimeToPayView]
ON              [SiconCFMSLCustomerAverageTimeToPayView].[SLCustomerAccountID]
=               [SLCustomerAccount].[SLCustomerAccountID]
GO

as suggested I have added OPTION (maxrecursion 0) to just above the last GO statement, however when within the create view statement it is giving a syntax error. If I run the query on its own, outside of a create view statement it works

2

There are 2 answers

2
Zohar Peled On BEST ANSWER

Usually, At the end of the select statement that uses the recurcive cte.
However, inside a view that will not work. A quick search got me to this post - that explains the correct way to do it.

Turns out you can't use the query hint inside the view, but you can and should use it in the query that calls the view.

Sample table:

CREATE TABLE T
(
    id int,
    parent int
)
INSERT INTO T VALUES (1, NULL), (2, 1), (3, 1), (4, 2), (5, 2), (6, 3), (7, 4), (8, 5);
GO

Create the view:

CREATE VIEW V
AS

WITH CTE AS
(
    SELECT id, parent
    FROM T 
    WHERE parent IS NULL
    UNION ALL

    SELECT t.id, t.parent
    FROM T
    INNER JOIN CTE ON t.parent = cte.id
)

SELECT *
FROM CTE

GO

Execute the view:

SELECT *
FROM V
OPTION (MAXRECURSION 2);
0
Marcello Miorelli On

there is a very nice script that I use to check foreign keys recursively by Ann Lewkowicz

However, I once had a database which had plenty of constraints, including foreign key constraints in some of the tables.

and while running the script above I got the following error:

The statement terminated. The maximum recursion 32767 has been exhausted before statement completion.

then I limited the output of the script using top and it all went out fine

 select top 100 *
 from   recurseWithFields 
--OPTION (MAXRECURSION 32767);