#sql-server #common-table-expression
#sql-сервер #common-table-expression
Вопрос:
У меня возникла проблема с отслеживанием последовательности выполнения следующего кода :
Код работает нормально
Я просто пытаюсь понять, как.
with MyCTE(x)
as
(
1) select x = convert(varchar(8000),'hello') // line 1
union all
3) select x 'a' from MyCTE where len(x) < 100 //line 3
)
select x from MyCTE
order by x
MSDN:
Семантика рекурсивного выполнения выглядит следующим образом:
Разделите выражение CTE на якорные и рекурсивные члены.
Запустите привязочный элемент (ы), создающий первый вызов или базовый набор результатов (T0).
Запустите рекурсивный элемент (ы) с Ti в качестве входных данных и Ti 1 в качестве выходных данных.
Повторяйте шаг 3, пока не будет возвращен пустой набор.
Возвращает результирующий набор. Это ОБЪЕДИНЕНИЕ ВСЕХ значений от T0 до Tn.
Этапы:
1) выполняется строка 1 (x = привет)
2) выполняется строка 3 (привет)
3) теперь он называет себя так: здесь x снова возвращается к hello!! (строка 1)
- согласно: строка 1, всякий раз, когда cte вызывает себя — x всегда должен быть сброшен! (или T0 обходится в рекурсивном?)
- какова роль для (x) части, которую он выполняет в MyCTE (x)? ввод или вывод?
Цитата:
Запустите рекурсивный элемент (ы) с Ti в качестве входных данных и Ti 1 в качестве выходных данных.
Насколько мне известно, (x) — это значение out, а не Input.
Комментарии:
1. Это теоретический вопрос, или вы уже запускали это?
2. @gbn — Привет! , я уже запускаю это, и оно работает, но я не могу узнать, как. —
whenever the cte calls itself - the x is always should be reset
, но это не так (и это нормально), но я не могу понять, почему: он говорит каждый раз :select x = convert(varchar(8000),'hello')
Ответ №1:
T0 / Line1 выполняется один раз в качестве привязки.
- строка 1 выполнена (привет)
- строка 3 выполняется (helloa), потому что LEN(hello) = 5 меньше 100
- строка 3 выполняется (helloaa), потому что LEN(helloa) = 6 меньше 100
- строка 3 выполняется (helloaaa), потому что LEN(helloaa) = 7 меньше 100
- строка 3 выполняется (helloaaaa), потому что LEN(helloaaaa) = 8 меньше 100
- строка 3 выполняется (helloaaaaa), потому что LEN(helloaaaa) = 9 меньше 100
- строка 3 выполняется (helloaaaaaa), потому что LEN(helloaaaa) = 10 меньше 100
…
С некоторыми комментариями
with MyCTE(x)
as
(
select x = convert(varchar(8000),'hello') -- Anchor, executed once
union all
select x 'a' from MyCTE where len(x) < 100 -- Recursion, executed n times
)
select x from MyCTE order by x
Во время выполнения это
select x = convert(varchar(8000),'hello') -- Anchor
union all
select 'hello' 'a' -- Recursion 1
union all
select 'helloa' 'a' -- Recursion 2
union all
select 'helloaa' 'a' -- Recursion 3
union all
select 'helloaaa' 'a' -- Recursion 4
union all
select 'helloaaaa' 'a' -- Recursion 5
...
Комментарии:
1. Как всегда — ты ВЕЛИКОЛЕПЕН. Спасибо. проблема заключалась в том, что я думал, что эта строка
1
ВСЕГДА выполняется….