2015-12-14 4 views
1

Я нашел это хранимая процедура в нашем коде:Ссылка CTE внутри CTE?

ALTER PROCEDURE [dbo].[MoveNodes] 
(
    @id bigint, 
    @left bigint, 
    @right bigint, 
    @parentid bigint, 
    @offset bigint, 
    @caseid bigint, 
    @userid bigint 

) 
AS 
BEGIN 
WITH q AS 
     (
     SELECT id, parent, lft, rgt, title, type, caseid, userid, 0 AS level, 
       CAST(LEFT(CAST(id AS VARCHAR) + REPLICATE('0', 10), 10) AS VARCHAR) AS bc 
     FROM [dbo].DM_FolderTree hc 
     WHERE id = @id and caseid = @caseid 
     UNION ALL 
     SELECT hc.id, hc.parent, hc.lft, hc.rgt, hc.title, hc.type, hc.caseid, hc.userid, level + 1, 
       CAST(bc + '.' + LEFT(CAST(hc.id AS VARCHAR) + REPLICATE('0', 10), 10) AS VARCHAR) 
     FROM q 
     JOIN [dbo].DM_FolderTree hc 
     ON  hc.parent = q.id   
     ) 
UPDATE [dbo].DM_FolderTree 
    SET lft = ((-lft) + @offset), rgt = ((-rgt) + @offset), userid = @userid 
    WHERE id in (select id from q) AND lft <= (-(@left)) AND rgt >= (-(@right)) AND caseid = @caseid; 
UPDATE [dbo].DM_FolderTree SET parent = @parentid, userid = @userid WHERE id = @id AND caseid = @caseid; 
END 

где вы заметите, что КТР q используется называется на UNION. Что именно мы здесь называем? Все до UNION, весь CTE? Что именно здесь происходит.

Я предполагаю, что этот код является законным, так как он был в производстве довольно долго (FLW, я знаю). Но все же я понятия не имею, что здесь происходит.

+0

Это рекурсивный запрос. Он вызывает CTE снова и снова, пока все идентификаторы и идентификаторы CaseID не пройдут по дереву. Подумайте о вложенности папок в каталог. Этот запрос просто подходит всем директорам, чтобы получить окончательный «путь к файлу» для всех файлов во всех папках. Обратите внимание, как Уровень начинается с 0 и затем добавляется. Второй раз, хотя уровень теперь равен 1 и становится 2, а затем 3 и так далее. Возьмите часть select cte '(с q as ...)' и замените обновление 'Select * from q' и запустите его. Просто вы можете увидеть, как это работает. – xQbert

+1

@xQbert Любая причина публикации этого комментария? Мне кажется, что это достойный ответ. – hvd

+0

Хорошо, теперь это ответ с некоторыми твиками. Это просто не вопрос программирования. – xQbert

ответ

3

Это рекурсивный запрос. Он вызывает CTE снова и снова, пока все идентификаторы и идентификаторы CaseID не пройдут по дереву.

Подумайте о вложенности папок в каталог. Этот запрос просто подходит всем директорам, чтобы получить окончательный «путь к файлу» для всех файлов во всех папках.

Обратите внимание, как Уровень начинается с 0 и затем добавляется. Второй раз, хотя уровень теперь равен 1 и становится 2, а затем 3 и так далее.

Чтобы лучше понять:

Захватите выберите КТР часть (with q as...) и заменить обновление с Select * from q и запустить его. Просто чтобы вы могли видеть, что он делает. Немного грубого обучения, чтобы начать с, но ходить, хотя пример, делая выше, поможет.

Конкретные ответы на вопросы:

Что именно мы здесь вызова?

Ваше здание - базовая линия, обозначающая все корни, с которой вы хотите начать, и затем пересекайте все уровни под этой корневой папкой. Итак, в основном вы ползаете по всей структуре для hc.parent = q.id

Все, что происходит перед UNION, весь CTE?

Весь cte. Рекурсия сильно крутая!