我在代码库中找到了这个存储过程:
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,我知道)。但是,我仍然不知道这里发生了什么。
答案 0 :(得分:3)
这是一个递归查询。它一次又一次地调用CTE,直到所有ID和CaseID都走到树上。
考虑在目录中嵌套文件夹。此查询简单地遍历所有控制器,以获得所有文件夹中所有文件的“文件路径”。
注意Level如何从0开始然后被添加到。第二次虽然等级现在为1并且变为2然后是3,依此类推。
为了更好地理解:
抓住选择的cte部分(with q as...)
并将更新替换为Select * from q
并运行它。这样你就可以看到它的作用。稍微粗略的学习开始,但通过做上述步骤通过一个例子将有所帮助。
问题的具体答案:
我们究竟在这里打电话?
构建一个基线,表示您希望开始的所有根,然后遍历该根/文件夹下的所有级别。因此,在本质上,您正在抓取hc.parent = q.id
UNION之前的一切,整个CTE?
整个cte。递归强大的东西很酷!