Как CTE работает внутри в sql? - PullRequest
0 голосов
/ 28 октября 2011

У меня проблема с отслеживанием последовательности выполнения следующего кода:

Код работает нормально

Я просто пытаюсь понять, как.

    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) теперь он называет себя так: здесь х снова вернулся к привету !! (строка 1)

  • в соответствии с: line 1 , всякий раз, когда cte вызывает себя - x всегда должен быть сброшен! (или T0 обходится в рекурсивном?)

  • Какую роль играет роль (x) в MyCTE (x)? вход или выход?

цитата:

Запустите рекурсивный элемент (ы) с Ti в качестве входа и Ti + 1 в качестве выхода.

Насколько мне известно (x) - это выходное значение, а не вход.

1 Ответ

4 голосов
/ 28 октября 2011

T0 / Line1 выполняется один раз как привязка.

  1. строка 1 выполняется (привет)
  2. строка 3 выполняется (привет), потому что LEN (привет) = 5 меньшезатем выполняется 100
  3. строка 3 (helloaa), потому что LEN (helloa) = 6 меньше 100
  4. строка 3 выполняется (helloaaa), потому что LEN (helloaa) = 7 меньше 100
  5. строка 3 выполняется (helloaaaa), потому что LEN (helloaaa) = 8 меньше, чем 100
  6. строка 3 выполняется (helloaaaaa), потому что LEN (helloaaaa) = 9 меньше, чем 100
  7. Строка 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
   ...
...