Mon CTE fonctionne dans une boucle infinie pour un client spécifique et je ne suis pas capable de savoir pourquoi.
Voici la requête:
;WITH ClassTree
AS (SELECT ID, NAME, Parent_ID
FROM TableName
WHERE ID = 1
UNION ALL
SELECT T.ID, T.NAME, T.Parent_ID
FROM TableName T WITH (NOLOCK)
JOIN ClassTree
ON Parent_ID = ClassTree.ID
)
SELECT * FROM ClassTree
Je pense que cela devrait trouver le problème de problème pour vous. Il ajoute un LEVEL
à votre hiérarchie, puis recherche un enregistrement d'identité individuel existant à plusieurs niveaux.
;WITH ClassTree
AS (SELECT ID, NAME, Parent_ID, 1 as 'Level'
FROM TableName
WHERE ID = 1
UNION ALL
SELECT T.ID, T.NAME, T.Parent_ID, Level + 1 as 'Level'
FROM TableName T WITH (NOLOCK)
JOIN ClassTree
ON Parent_ID = ClassTree.ID
)
SELECT *
FROM ClassTree c1
WHERE EXISTS (SELECT 1 FROM ClassTree c2
WHERE c2.id = c1.id
AND c2.Level > c1.level)
Voici un petit quelque chose que vous pouvez utiliser pour trouver vos cycles.
declare @T table
(
ID int,
Parent_ID int
)
insert into @T values
(1, 3),(2, 1),(3, 2), -- This is a cycle
(4, 4), -- This is a cycle
(5, null),(6, 5),(7, 6) -- This is not a cycle
;with C as
(
select T.ID,
T.Parent_ID,
cast(',' + cast(ID as varchar(10)) + ',' as varchar(max)) as Path,
0 Cycle
from @T as T
union all
select T.ID,
T.Parent_ID,
C.Path + cast(T.ID as varchar(10)) + ',',
case when C.Path like '%,'+cast(T.ID as varchar(10))+',%'
then 1
else 0
end
from @T as T
inner join C
on T.Parent_ID = C.ID
where C.Cycle = 0
)
select *
from C
where Cycle = 1
Résultat:
ID Parent_ID Path Cycle
----------- ----------- ---------- -----------
4 4 ,4,4, 1
3 2 ,3,1,2,3, 1
2 1 ,2,3,1,2, 1
1 3 ,1,2,3,1, 1
La toute première chose que je ferais, c'est changer ceci:
JOIN ClassTree
ON Parent_ID = ClassTree.ID
pour ça:
JOIN ClassTree
ON t.Parent_ID = ClassTree.ID
Il peut être essentiel de rejoindre ClassTree à lui-même depuis que vous n'avez pas spécifié l'alias de table dans la jointure.