2016-03-24 5 views
1

Warum diese Rekursion nicht aufhören?T-SQL Warum Rekursion nicht stoppen?

DECLARE @T TABLE(id INT) 
INSERT INTO @T(id) VALUES (1), (2) 

WITH cte AS(
    SELECT id, 1 a FROM @T WHERE id = 1 
    UNION ALL 
    SELECT T.id, O.id 
    FROM @T T outer apply(SELECT * FROM cte WHERE cte.id = T.id) O 
    WHERE O.id IS NULL 
    ) 
SELECT * FROM cte 

Wenn ich temporäre Tabelle #cte verwenden und rekursiven Teil repeate - nach einigen Iterationen 0 Datensätze sein ...

+0

@sagi ... welches ist [eine bekannte Technik, von Microsoft empfohlen] (https://technet.microsoft.com/en-us/library/ms186243 (v = sql.105) .aspx); Ich nehme an, dass Alex erwartet, dass die Rekursion beendet wird. –

Antwort

0

ich dies als Kommentar hinzufügen würde, aber ich habe nicht genügend Ruf um es zu tun.

Die Ankerelementdefinition Ihres rekursiven CTE ist korrekt. Aber nicht die rekursive Elementdefinition. Da für die Abfrage immer ein Datensatz zurückgegeben wird

die Rekursion geht für immer weiter.

Try WO O.id IS NICHT NULL

Für weitere Informationen: Recursive CTEs MSDN

1

Sie mit einer einzigen Zeile beginnen:

SELECT id, 1 a FROM @T WHERE id = 1 
1  1 

1. Rekursion gibt zwei Reihen (basierend auf CROSS APPLY) und die WHERE entfernt eine von ihnen:

SELECT T.id, O.id 
FROM @T T outer apply(SELECT * FROM cte WHERE cte.id = T.id) O 
WHERE O.id IS NULL 

1  1  -- filtered 
2  NULL -- returned and used for next recursion 

jeweils folgende Rekursion gibt zwei Reihen:

SELECT T.id, O.id 
FROM @T T outer apply(SELECT * FROM cte WHERE cte.id = T.id) O 
WHERE O.id IS NULL 

1  NULL -- returned and used for next recursion 
2  NULL -- returned and used for next recursion 

Das Ergebnis ist richtig, es ist wahrscheinlich die Logik, die Sie anwenden versuchen.

Was versuchen Sie eigentlich? Die Abfrage as-is ist ziemlich nutzlos ...

Verwandte Themen