在CTE中参考CTE?

时间:2015-12-14 17:07:48

标签: sql sql-server tsql

我在代码库中找到了这个存储过程:

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上正在使用CTE UNION。我们究竟在这叫什么? UNION之前的所有事情,整个CTE?到底发生了什么。

我假设这段代码是合法的,因为它已经生产了很长一段时间(FLW,我知道)。但是,我仍然不知道这里发生了什么。

1 个答案:

答案 0 :(得分:3)

这是一个递归查询。它一次又一次地调用CTE,直到所有ID和CaseID都走到树上。

考虑在目录中嵌套文件夹。此查询简单地遍历所有控制器,以获得所有文件夹中所有文件的“文件路径”。

注意Level如何从0开始然后被添加到。第二次虽然等级现在为1并且变为2然后是3,依此类推。

为了更好地理解:

抓住选择的cte部分(with q as...)并将更新替换为Select * from q并运行它。这样你就可以看到它的作用。稍微粗略的学习开始,但通过做上述步骤通过一个例子将有所帮助。

问题的具体答案:

我们究竟在这里打电话?

构建一个基线,表示您希望开始的所有根,然后遍历该根/文件夹下的所有级别。因此,在本质上,您正在抓取hc.parent = q.id

的整个结构

UNION之前的一切,整个CTE?

整个cte。递归强大的东西很酷!