2016-12-16 3 views
2

J'ai une requête qui renvoie une erreur avec les niveaux maximum de récursion dépassée.SQL Server: la récursivité maximale 100 a été épuisée avant la fin de l'instruction

Je sais comment résoudre ce problème en ajoutant OPTION (maxrecursion 0) à la requête cependant, j'ai essayé d'ajouter ceci à divers endroits dans la requête et je ne peux pas trouver où le mettre où la syntaxe est valide.

Quelqu'un peut-il me donner des indications sur l'endroit où, à mon avis, l'indice de requête doit être inséré?

/****** 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 

comme suggéré que j'ai ajouté OPTION (maxrecursion 0) juste au-dessus de la dernière déclaration de GO, mais quand dans la déclaration vue créer donne une erreur de syntaxe. Si je lance la requête elle-même, en dehors d'une instruction create view cela fonctionne

+3

A la fin de l'instruction select qui utilise le recurcive cte –

Répondre

5

Généralement, À la fin de l'instruction select qui utilise le cte recurcive.
Cependant, dans une vue qui ne fonctionnera pas. Une recherche rapide m'a eu à this post - qui explique la bonne façon de le faire.

Il s'avère que vous ne pouvez pas utiliser l'indicateur de requête dans la vue, mais vous pouvez et devez l'utiliser dans la requête qui appelle la vue.

Exemple de tableau:

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 

Création de la vue:

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 la vue:

SELECT * 
FROM V 
OPTION (MAXRECURSION 2); 
+0

Merci, cela fonctionne si j'exécute la requête sur son propre, cependant, quand je l'ai mis dans une déclaration CreateView son retour avec un erreur de syntaxe, j'ai mis à jour l'instruction de requête de question pour inclure tout le code – WraithNath

+0

Voir ma réponse éditée. –

+0

Merci, Ill travailler mon chemin jusqu'à la chaîne de vues jusqu'à ce que je trouve où il doit aller, il est appelé à partir d'une procédure stockée au niveau supérieur qui prend deux paramètres pour la plage de dates. J'ai déjà un indice de récursivité max sur la table de dates sur laquelle il pivote, donc j'ai l'impression que j'en ai besoin d'un autre sur la vue qui est pivotée. – WraithNath