gpt4 book ai didi

获取树形数据的全路径

转载 作者:我是一只小鸟 更新时间:2023-02-21 06:31:15 26 4
gpt4 key购买 nike

我们经常要用到树形数据,比如:部门、文章栏目、行政区划……,而且有时还需要用到这些数据的全路径,比如:四川省 > 遂宁市 > 船山区.

为了避免每次要使用全路径时都拼接一次,我们可以在数据库增加一个字段来保存全路径,并且使用触发器来生成全路径.

典型的表结构如下:

 由于新增的节点都处于末级,没有子节点,只需要修改新增节点的全路径,如下:

                        
                          ALTER
                        
                        
                          TRIGGER
                        
                        
                          [
                        
                        
                          dbo
                        
                        
                          ]
                        
                        .
                        
                          [
                        
                        
                          trDeptInsert
                        
                        
                          ]
                        
                        
                          
    
                        
                        
                          ON
                        
                        
                          [
                        
                        
                          dbo
                        
                        
                          ]
                        
                        .
                        
                          [
                        
                        
                          tbDept
                        
                        
                          ]
                        
                        
                          
    AFTER 
                        
                        
                          INSERT
                        
                        
                          AS
                        
                        
                          SET
                        
                         NOCOUNT 
                        
                          ON
                        
                        
                          --
                        
                        
                          连接inserted表得到新增的数据
                        
                        
                          
--
                        
                        
                          连接tbDept表取得上级节点路径,如果是顶层,就没有上级节点,所以需要LEFT JOIN
                        
                        
                          
--
                        
                        
                          如果是顶层,全路径就是节点名称,否则,就是上级节点全路径+当前节点名称
                        
                        
                          UPDATE
                        
                        
                           A

                        
                        
                          SET
                        
                         Path 
                        
                          =
                        
                        
                          CASE
                        
                        
                          WHEN
                        
                         A.ParentID 
                        
                          =
                        
                        
                          0
                        
                        
                          THEN
                        
                         A.Title 
                        
                          ELSE
                        
                         B.Path 
                        
                          +
                        
                        
                          '
                        
                        
                           > 
                        
                        
                          '
                        
                        
                          +
                        
                         A.Title 
                        
                          END
                        
                        
                          FROM
                        
                         tbDept A 
                        
                          INNER
                        
                        
                          JOIN
                        
                         inserted I 
                        
                          ON
                        
                         A.ID 
                        
                          =
                        
                         I.ID 
                        
                          LEFT
                        
                        
                          JOIN
                        
                         tbDept B 
                        
                          ON
                        
                         A.ParentID 
                        
                          =
                        
                         B.ID
                      

修改节点后,要做判断,只有修改了节点名称或者所属上级节点,才需要修改全路径,同时,也要修改所有子节点的全路径,如下:

                        
                          ALTER
                        
                        
                          TRIGGER
                        
                        
                          [
                        
                        
                          dbo
                        
                        
                          ]
                        
                        .
                        
                          [
                        
                        
                          trDeptUpdate
                        
                        
                          ]
                        
                        
                          
    
                        
                        
                          ON
                        
                        
                          [
                        
                        
                          dbo
                        
                        
                          ]
                        
                        .
                        
                          [
                        
                        
                          tbDept
                        
                        
                          ]
                        
                        
                          
    AFTER 
                        
                        
                          UPDATE
                        
                        
                          AS
                        
                        
                          SET
                        
                         NOCOUNT 
                        
                          ON
                        
                        
                          ;

                        
                        
                          --
                        
                        
                          递归查出修改了的节点以及他们的所有后代节点
                        
                        
                          
--
                        
                        
                          连接inserted和deleted表,并使用I.ParentID <> D.ParentID OR I.Title <> D.Title判断是否修改了名称和所属父节点
                        
                        
                          WITH
                        
                        
                          temp
                        
                        
                          AS
                        
                        
                           (
    
                        
                        
                          SELECT
                        
                         A.ID 
                        
                          FROM
                        
                         tbDept A 
                        
                          INNER
                        
                        
                          JOIN
                        
                         inserted I 
                        
                          ON
                        
                         A.ID 
                        
                          =
                        
                         I.ID 
                        
                          INNER
                        
                        
                          JOIN
                        
                         deleted D 
                        
                          ON
                        
                         I.ID 
                        
                          =
                        
                        
                           D.ID
    
                        
                        
                          WHERE
                        
                         I.ParentID 
                        
                          <>
                        
                         D.ParentID 
                        
                          OR
                        
                         I.Title 
                        
                          <>
                        
                        
                           D.Title
    
                        
                        
                          UNION
                        
                        
                          ALL
                        
                        
                          SELECT
                        
                         tbDept.ID 
                        
                          FROM
                        
                        
                          temp
                        
                        
                          INNER
                        
                        
                          JOIN
                        
                         tbDept 
                        
                          ON
                        
                        
                          temp
                        
                        .ID 
                        
                          =
                        
                        
                           tbDept.ParentID
)

                        
                        
                          --
                        
                        
                          CTE数据只能使用一次,所以需要写入临时表,同时增加行号,以便遍历
                        
                        
                          SELECT
                        
                         ID, RowID 
                        
                          =
                        
                         ROW_NUMBER() 
                        
                          OVER
                        
                        (
                        
                          ORDER
                        
                        
                          BY
                        
                         ID) 
                        
                          INTO
                        
                         #
                        
                          TEMP
                        
                        
                          FROM
                        
                        
                          temp
                        
                        
                          --
                        
                        
                          遍历上面得到的所有节点ID
                        
                        
                          DECLARE
                        
                        
                          @RowCount
                        
                        
                          int
                        
                        
                          =
                        
                         (
                        
                          SELECT
                        
                        
                          COUNT
                        
                        (
                        
                          *
                        
                        ) 
                        
                          FROM
                        
                         #
                        
                          TEMP
                        
                        ), 
                        
                          @RowID
                        
                        
                          int
                        
                        
                          =
                        
                        
                          1
                        
                        
                          --
                        
                        
                          行数,行号
                        
                        
                          WHILE
                        
                        
                          @RowCount
                        
                        
                          >=
                        
                        
                          @RowID
                        
                        
                          BEGIN
                        
                        
                          DECLARE
                        
                        
                          @ID
                        
                        
                          int
                        
                        
                          SELECT
                        
                        
                          @ID
                        
                        
                          =
                        
                         ID 
                        
                          FROM
                        
                         #
                        
                          TEMP
                        
                        
                          WHERE
                        
                         RowID 
                        
                          =
                        
                        
                          @RowID
                        
                        
                          ;
    
                        
                        
                          --
                        
                        
                          递归得到当前节点及其所有父节点名称
                        
                        
                          WITH
                        
                        
                          temp
                        
                        
                          AS
                        
                        
                           (
        
                        
                        
                          SELECT
                        
                         Title, ParentID, 
                        
                          Level
                        
                        
                          =
                        
                        
                          0
                        
                        
                          FROM
                        
                         tbDept 
                        
                          WHERE
                        
                         ID 
                        
                          =
                        
                        
                          @ID
                        
                        
                          UNION
                        
                        
                          ALL
                        
                        
                          SELECT
                        
                         A.Title, A.ParentID, 
                        
                          Level
                        
                        
                          -
                        
                        
                          1
                        
                        
                          FROM
                        
                         tbDept A 
                        
                          INNER
                        
                        
                          JOIN
                        
                        
                          temp
                        
                        
                          ON
                        
                         A.ID 
                        
                          =
                        
                        
                          temp
                        
                        
                          .ParentID
    )
    
                        
                        
                          --
                        
                        
                          使用FOR XML PATH拼接出节点全路径
                        
                        
                          --
                        
                        
                          使用STUFF函数去掉前面多余的连接符号
                        
                        
                          --
                        
                        
                          注意使用TYPE和.value('.','NVARCHAR(MAX)'),否则尖括号会被转义,并且value只能小写
                        
                        
                          UPDATE
                        
                        
                           tbDept
    
                        
                        
                          SET
                        
                         Path 
                        
                          =
                        
                        
                          STUFF
                        
                        ((
                        
                          SELECT
                        
                        
                          '
                        
                        
                           > 
                        
                        
                          '
                        
                        
                          +
                        
                        Title 
                        
                          FROM
                        
                        
                          temp
                        
                        
                          ORDER
                        
                        
                          BY
                        
                        
                          Level
                        
                        
                          FOR
                        
                         XML PATH(
                        
                          ''
                        
                        ),TYPE).value(
                        
                          '
                        
                        
                          .
                        
                        
                          '
                        
                        ,
                        
                          '
                        
                        
                          NVARCHAR(MAX)
                        
                        
                          '
                        
                        ),
                        
                          1
                        
                        ,
                        
                          3
                        
                        ,
                        
                          ''
                        
                        
                          )
    
                        
                        
                          WHERE
                        
                         ID 
                        
                          =
                        
                        
                          @ID
                        
                        
                          SET
                        
                        
                          @RowID
                        
                        
                          =
                        
                        
                          @RowID
                        
                        
                          +
                        
                        
                          1
                        
                        
                          END
                        
                      

数据示例如下:

  。

  。

最后此篇关于获取树形数据的全路径的文章就讲到这里了,如果你想了解更多关于获取树形数据的全路径的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com