zoukankan      html  css  js  c++  java
  • 自动维护路径信息的Sql Server无限级目录表

    我做的网站基本上都要用到一个无限级的目录表,用来分门别类组织各种文章类的信息。这个表只有三个字段(Id,ParentId,Name),一直就是这样用也没出现过什么问题。直到昨天,碰到了一个问题。我需要知道某个目录下面所有的子孙目录都有哪些。如果以Id或ParentId来查找的话,只能取得父Id和子Id,却不知道爷爷Id、老爷Id、孙子Id、重孙Id...。

    于是就在博问上发表了问题:http://space.cnblogs.com/question/3963/

    有园友提示在表中增加一个路径字段,也有园友给出了程序的实现代码,以循环方式来取得。我觉得在表中记录路径信息在使用当中相对更方便一些,效率可能也更高一些。

    但是要维护这些路径信息也够麻烦的,每次增删改一个目录都要修改牵涉到它的每条记录。于是乎:-) 我就考虑能不能在表上做个触发器,自动完成这些任务呢。

    说干就干,首先修改目录表的结构,增加两个字段(IdPath, NamePath),如下图:

    再写一个存储过程。接受一个@Id参数,来更新Id=@Id的目录的路径信息。代码如下:

     1 CREATE PROCEDURE [dbo].[SetSortPath] 
     2 @Id    int
     3 AS
     4 SET NOCOUNT ON;
     5 
     6 DECLARE    @PId        varchar(10),
     7     @ParentId    int,
     8     @Name        nvarchar(500),
     9     @IdPath        varchar(500),
    10     @NamePath    nvarchar(500);
    11         
    12 SET @IdPath='/';
    13 SET @NamePath='/';
    14 SELECT @PId=[ParentId] FROM [Sort] WHERE [Id]=@Id;
    15 
    16 WHILE (@PId IS NOT NULL)
    17 BEGIN
    18     SELECT @ParentId=[ParentId]@Name=[Name] FROM [Sort] WHERE [Id]=@PId;
    19     
    20     SET @IdPath = '/' + @PId + @IdPath;
    21     SET @NamePath = '/' + @Name + @NamePath;
    22 
    23     IF(@ParentId <> @PId)
    24         SET @PId=@ParentId;
    25     ELSE
    26         SET @PId=NULL;
    27 END
    28 
    29 IF(@IdPath='/')
    30     UPDATE [Sort] SET [IdPath]=NULL[NamePath]=NULL WHERE [Id]=@Id;
    31 ELSE
    32     UPDATE [Sort] SET [IdPath]=@IdPath[NamePath]=@NamePath WHERE [Id]=@Id;

    最后是给目录表创建一个触发器。任务是每次添加或修改目录,就从inserted表中遍历每条记录,使用上面的存储过程更新它和它的子孙目录。代码如下:

     1 CREATE TRIGGER [dbo].[Trig_SetPath]
     2    ON  [dbo].[Sort]
     3    AFTER INSERTUPDATE
     4 AS 
     5 SET NOCOUNT ON;
     6 
     7 DECLARE @Id     varchar(11);
     8 
     9 DECLARE    cur_Inserted CURSOR FOR SELECT [Id] FROM Inserted;    --从Inserted表创建游标
    10 OPEN cur_Inserted;
    11 
    12 FETCH FROM cur_Inserted INTO @Id;
    13 WHILE(@@Fetch_Status=0)
    14 BEGIN
    15 
    16     EXEC [SetSortPath] @Id=@Id;    --更新自身
    17 
    18     DECLARE cur_Sort CURSOR FOR SELECT [Id] FROM [Sort] WHERE [IdPath] LIKE '%/'+@Id+'/%';    --以所有子孙目录创建游标
    19     OPEN cur_Sort;
    20     FETCH FROM cur_Sort INTO @Id;
    21     WHILE(@@Fetch_Status=0)
    22     BEGIN
    23         EXEC [SetSortPath] @Id=@Id;    --更新子目录
    24         FETCH FROM cur_Sort INTO @Id;
    25     END    
    26     CLOSE  cur_Sort;
    27     Deallocate  cur_Sort;
    28 
    29     FETCH FROM cur_Inserted INTO @Id;
    30 
    31 END
    32 CLOSE  cur_Inserted;
    33 Deallocate  cur_Inserted;

    我简单测试了一下,效果还行,支持批量添加和批量修改。

  • 相关阅读:
    excel2007灵活计算2个日期之间的工作日
    bat
    eclipse Maven操作出现No compiler is provided in this environment.Perhaps you are running on a JRE rather than a JDK?
    将BeyondCompare设置为TortoiseSVN的扩展比较工具
    python_Excel_xlwt
    Pyqt5_实例1
    Word使用技巧——持续更新
    python_serial
    Pyqt5_Python运用过程中一些问题和技巧
    Pyqt5_QfileDialog
  • 原文地址:https://www.cnblogs.com/luotong/p/1340548.html
Copyright © 2011-2022 走看看