Из некоторого тестирования выясняется, что рекурсия SQL происходит на глубину, начиная с последней строки, возвращенной из исходного запроса. Как только он достиг MAXRECURSION
, запрос завершается с ошибкой (например, The statement terminated. The maximum recursion 2 has been exhausted before statement completion.
) и возвращает все результаты, которые он достиг до ошибки. В этом можно убедиться, вставив 2,1 вместо 1,2 в оператор вставки или вставив 1,2,3 в таблицу @Number
. Если вы вставите 1,2,3 в @Number
, ваши возвращенные результаты будут
1 -- From anchor
2 -- From anchor
3 -- From anchor
3 -- 1st recursion from last row of anchor query
3 -- Recursion from the row from the line above this (2nd recursion)
-- Query terminates after MAXRECURSION reached on an item and does not attempt recursion on 1 or 2
Как правило, при использовании рекурсии вы присоединяете CTE к себе или к какой-либо другой таблице с некоторыми критериями в операторе where или критериями on в объединении, которые ограничивают рекурсию на основе доступных данных (а не просто повторную рекурсию через такие же элементы). Например (используя ту же таблицу @Number
из вашего вопроса):
DECLARE @Number TABLE (Number INT);
INSERT @Number
(
Number
)
VALUES (1),
(2);
WITH _cte2
AS
(SELECT
Number
,0 as 'RecursionCount'
FROM
@Number
UNION ALL
SELECT
Number
,RecursionCount + 1
FROM
_cte2
WHERE
RecursionCount <= 1
)
SELECT * FROM _cte2 OPTION (MAXRECURSION 2);
В приведенном выше примере запрос ограничит собственную рекурсию в операторе where и никогда не достигнет MAXRECURSION, поэтому запрос сможет завершиться. Вы также заметите, что порядок возврата результатов подтверждает мое подозрение, что рекурсия - это глубина, начинающаяся с последнего элемента:
Number RecursionCount
1 0
2 0
2 1
2 2
1 1
1 2