繁体   English   中英

转储SQL Server 2008 R2中父/子类型记录的完整路径列表

[英]Dump list of full paths of parent/child type records in SQL Server 2008 R2

我需要检索存储在数据库中的组(文件夹)的完整路径列表:

select * from groups;

group_id    parent_group_id    name
--------    ---------------    -------------------------------
1           NULL               Root
2           1                  Folder1
3           2                  Folder2
4           3                  Folder3

组的可能深度没有限制(几乎可以无限期地嵌套),所以我事先并不知道我可以拥有多少级别。

我希望能够从查询中获取以下结果并将其加载到一个表中,我可以使用该表在其他查询中使用group_ids加入完整路径:

group_id   path
--------   --------------------------------------------
1          /Root
2          /Root/Folder1
3          /Root/Folder1/Folder2
4          /Root/Folder1/Folder2/Folder3

我一直在寻找其他一些有类似需求的例子,但它似乎永远不能完全符合我的要求,如果没有一个明确的例子,我就无法独自完成它。

我唯一能想到的是将同一个表的别名加到最大级别,这可能很多,这是不切实际的。 我需要一种方法以某种方式递归循环每个组并向上移动树,将路径附加到变量直到我结束,然后将最深的子ID及其完整路径存储在表中。

表现也很重要。 这是一个生产数据库,我无法承受减速,这就是为什么我只想在我需要它然后重用静态数据时才转储它。 最终,我想转储数千个记录,每个记录链接到group_id并打印完整路径。

如果没有免费提供给我全部内容,有人可以指出我正确的方向并且可能给我一个通用的例子来复制吗?

我们正在使用SQL Server 2008 R2。

听起来像使用递归CTE的东西可能能够解决。 CTE(或公用表表达式)将允许您创建类似于表的结构,而无需创建表或视图。 CTE还允许您创建递归查询,在您的情况下可以提供极大的帮助。 该结构允许您将CTE加入到自身中,从而为您在此处实现的“级联”类型的结果提供借贷。

例如,你可以这样做:

WITH grouppaths (group_id, group_path) AS
(
    SELECT group_id, pathname
    FROM GroupPath
    WHERE parent_group_id IS NULL

    UNION ALL

    SELECT gp.group_id, gps.group_path + '/' + gp.pathname
    FROM GroupPath gp
    JOIN grouppaths gps ON gps.group_id = gp.parent_group_id
)

SELECT 
  group_id, group_path
FROM
  grouppaths

你可以使用SqlFiddle 在这里查看。

Microsoft提供有关在此处使用CTE的信息和示例: http//msdn.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx

更具体地说,此链接提供了有关递归 CTE的更多信息: http//msdn.microsoft.com/en-us/library/ms186243%28v=sql.105%29.aspx

根据Matt Johnson发布的链接,我能够解决我的挑战:

WITH group_paths (group_id, group_path)
AS
(
-- Anchor member definition
    SELECT g.group_id, cast('/'+g.name as varchar(max)) as group_path
    FROM dbo.blgroup AS g
    WHERE parent_group_id=0
    UNION ALL
-- Recursive member definition
    SELECT g.group_id, cast(group_path + '/' + g.name as varchar(max))
    FROM dbo.blgroup AS g
    INNER JOIN group_paths AS gp
        ON g.parent_group_id = gp.group_id
)
-- Statement that executes the CTE
SELECT group_id, group_path
FROM group_paths

结果看起来像这样,这正是我所需要的:

group_id    group_path
----------- ----------------------------------------
1000001     /Servers
1000002     /Depot
1000003     /Jobs
1000004     /Component Templates
1000006     /System Packages
1000005     /Components
1000008     /Patch Repository
1000007     /Device
1000010     /Device/Imported
1000011     /Device/Provisioned
1000009     /Patch Repository/Patches By Subscription
2000148     /Components/Customers

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM