zoukankan      html  css  js  c++  java
  • 實現樹樁類型結構及其相應的操作【增刪查改和移動】

    一、創建樹樁結構對應的表

    1、創建樹樁層次結構表

    樹狀結構表採用鏈結構的設計方式,每個節點包含一個當前節點指針ID、下一節點指針ID,以及當前節點的相關信息:節點名稱、順序、有效性、是否為葉子、層次,以下為創建表結構的SQL語句

        CREATE TABLE [dbo].[dispatch_type_config](
         [type_id] [nvarchar](50) NOT NULL,
         [b_type_id] [nvarchar](50) NOT NULL,
         [type_name_cn] [nvarchar](200) NOT NULL,
         [type_name_tw] [nvarchar](200) NOT NULL,
         [type_name_en] [nvarchar](300) NOT NULL,
         [sort] [int] NOT NULL,
         [is_enable] [bit] NOT NULL,
         [belong_client] [bit] NULL,
         [is_leaf] [bit] NULL,
         [layer] [int] NOT NULL,
         CONSTRAINT [PK_dispatch_type_config] PRIMARY KEY CLUSTERED 
        (
         [type_id] ASC,
         [b_type_id] ASC
        )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
        ) ON [PRIMARY]
        GO
        ALTER TABLE [dbo].[dispatch_type_config] ADD  CONSTRAINT [DF_dispatch_type_config_is_enable]  DEFAULT ((1)) FOR [is_enable]
        GO
        ALTER TABLE [dbo].[dispatch_type_config] ADD  CONSTRAINT [DF_dispatch_type_config_belong_client]  DEFAULT ((0)) FOR [belong_client]
        GO
        ALTER TABLE [dbo].[dispatch_type_config] ADD  CONSTRAINT [DF_dispatch_type_config_is_leaf]  DEFAULT ((1)) FOR [is_leaf]
        GO

    2、創建樹樁葉子節點對應的信息配置表

    樹狀葉子節點的信息配置表,是葉子節點才有的信息表,結合具體需求設計自己需要的欄位,以下為創建表結構的SQL語句

        CREATE TABLE [dbo].[dispatch_type_leaf](
         [dispatch_rowid] [nvarchar](50) NOT NULL,
         [ctrl_type] [nvarchar](50) NULL,
         [subject] [nvarchar](500) NULL,
         [context] [nvarchar](3000) NULL,
         [has_case] [bit] NULL,
         [is_show] [bit] NULL,
         CONSTRAINT [PK_dispatch_type_leaf] PRIMARY KEY CLUSTERED 
        (
         [dispatch_rowid] ASC
        )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
        ) ON [PRIMARY]
        GO
        ALTER TABLE [dbo].[dispatch_type_leaf] ADD  CONSTRAINT [DF_dispatch_type_leaf_has_case]  DEFAULT ((0)) FOR [has_case]
        GO
        ALTER TABLE [dbo].[dispatch_type_leaf] ADD  CONSTRAINT [DF_dispatch_type_leaf_is_show]  DEFAULT ((1)) FOR [is_show]
        GO

    二、獲取樹樁結構的數據

    由於樹狀層次結構表採用了鏈結構的設計方式,因此要想獲得所有樹狀結構節點的數據需要採用循環inner join的方式,又因設限具體的層次數量,故而將循環inner join的SQL以字符串的形式先組合起來,然後再通過exec來獲取數據。

        -- [dbo].[dispatch_GetType] 'cn','0'
        ALTER  proc [dbo].[dispatch_GetType]
        (
          @language nvarchar(10),
          @bSetting nvarchar(10)
        )
        AS
        Begin
     
         declare @sql nvarchar(max)
         declare @select nvarchar(max)
         declare @from nvarchar(max)
         declare @where nvarchar(max)
         declare @orderby nvarchar(max)
         declare @pid nvarchar(20)
         declare @id nvarchar(20)
         declare @index int
         declare @num int
         declare @maxNum int
         set @sql=''
         select @maxNum=max(layer) from dispatch_type_config where is_leaf='1'
         declare _cursor cursor local for
         select distinct layer from dispatch_type_config where is_leaf='1'
         open _cursor
         fetch next from _cursor into @num
         while @@FETCH_STATUS=0
         begin
           set @index=1
           set @id=CONVERT(nvarchar,@index)
           set @select=' select A'+@id+'.[type_id] as type_id'+@id+' ,A'+@id+'.type_name_'+@language+' as type_name'+@id+' ,A'+@id+'.is_enable as is_enable'+@id+' ,A'+@id+'.sort as sort'+@id
           set @from=' from dispatch_type_config A'+@id
           if(@sql='') set @orderby=' order by sort'+@id
           set @index=@index+1
           while @index<=@num
           begin
           set @pid=@id
           set @id=CONVERT(nvarchar,@index)
           set @select=@select+' ,A'+@id+'.[type_id] as type_id'+@id+' ,A'+@id+'.type_name_'+@language+' as type_name'+@id+' ,A'+@id+'.is_enable as is_enable'+@id+' ,A'+@id+'.sort as sort'+@id
           set @from=@from+' inner join dispatch_type_config A'+@id+' on A'+@pid+'.[b_type_id]=A'+@id+'.[type_id] and A'+@pid+'.layer='+@pid+' and A'+@id+'.layer='+@id
           if(@sql='') set @orderby=@orderby+' ,sort'+@id
           set @index=@index+1
           end
           set @pid=@id
           while @index<=@maxNum
           begin
           set @id=CONVERT(nvarchar,@index)
           set @select=@select+' ,'''' as type_id'+@id+' ,'''' as type_name'+@id+' ,'''' as is_enable'+@id+' ,'''' as sort'+@id
           if(@sql='') set @orderby=@orderby+' ,sort'+@id
           set @index=@index+1
           end
       
           set @select=@select+' ,A'+@pid+'.[type_id] as dispatch_rowid ,B.has_case ,B.ctrl_type ,A'+@pid+'.b_type_id, A'+@pid+'.belong_client as dispatch_belong '
           set @from=@from+' left join dispatch_type_leaf B on A'+@pid+'.[type_id]=B.dispatch_rowid and B.is_show=''1'' '
           set @where=' where A'+@pid+'.is_leaf=''1'' '
           if(@bSetting='0') set @where=@where+' and  A'+@pid+'.is_enable=''1'' '
       
           if(@sql='') set @sql=@select+@from+@where
           else set @sql=@sql+' union '+@select+@from+@where
           fetch next from _cursor into @num
         end
     
         close _cursor
         deallocate _cursor
     
         set @sql=@sql+@orderby
         exec(@sql)
        End

    三、將第二步獲取的樹狀結構數據轉換為zTree需要的JSON字符串

    1、定義一個樹樁節點對應的json模板

    private static string nodeModel = ""id":"{0}","pId":"{1}","bId":"{2}","name":"{3}","is_enable":"{4}","isParent":"{5}"{6}";

    2、將DataTable轉換為JSON字符串

    對於獲取的樹狀層次結構數據是以Row的形式,要想轉換為zTree需要的層次結構(父節點一條記錄,其子節點為N條記錄,每條子節點又有N條記錄……)的形式,故而需要逐層構造zTree需要的數據,首先需要確定根節點,然後依次是各個層次中的第一個節點(第一層中的第一個節點……,第N層中的第一個節點,……最後一層中的所有葉子節點),然後是各層中的第二個節點,……。因此採用遞歸的方式來處理,具體實現代碼如下:

            //對DataRow進行操作
            private void getDispatchItem(int n, List nums, List types, DataRow dr, StringBuilder sb)
            {
                if (n == 0) { return; }
                if (types[n - 1] != dr["type_id" + n.ToString()].ToString() || dr["type_id" + n.ToString()].ToString() == "")
                {
                    getDispatchItem(n - 1, nums, types, dr, sb);
                    types[n - 1] = dr["type_id" + n.ToString()].ToString().Trim();
                    if (types[n - 1] == "") { return; }
                    string pId = "", str = ","open":"true"";
                    if (n >= 2) { pId = types[n - 2]; if (n >= 3) { str = ","open":"false""; } }
                    //葉子節點或者沒有節點的父節點
                    if (n == types.Count || dr["type_id" + (n + 1).ToString()].ToString() == "")
                    {
                        sb.AppendFormat(nodeModel, dr["dispatch_rowid"].ToString(), pId, dr["b_type_id"].ToString(), dr["type_name" + n.ToString()].ToString(), dr["is_enable" + n.ToString()].ToString(), false, ","open":"false","type":"" + dr["ctrl_type"].ToString() + "","has_case":"" + dr["has_case"].ToString() + """);
                        //sb.AppendFormat(nodeModel, dr["dispatch_rowid"].ToString(), n == 1 ? "0" : types[n - 2], dr["b_type_id"].ToString(), dr["type_name" + n.ToString()].ToString(), false, ","open":"false","type":"" + dr["ctrl_type"].ToString() + "","has_case":"" + dr["has_case"].ToString() + """);
                    }
                    else
                    {
                        //if (n == 1) { sb.AppendFormat(nodeModel, types[n - 1], "0", dr["type_id" + (n + 1).ToString()].ToString(), dr["type_name" + n.ToString()].ToString(), true, ","open":"true""); }
                        //else if (n == 2) { sb.AppendFormat(nodeModel, types[n - 1], types[n - 2], dr["type_id" + (n + 1).ToString()].ToString(), dr["type_name" + n.ToString()].ToString(), true, ","open":"true""); }
                        //else { sb.AppendFormat(nodeModel, types[n - 1], types[n - 2], dr["type_id" + (n + 1).ToString()].ToString(), dr["type_name" + n.ToString()].ToString(), true, ","open":"false""); }
                        sb.AppendFormat(nodeModel, types[n - 1], pId, dr["type_id" + (n + 1).ToString()].ToString(), dr["type_name" + n.ToString()].ToString(), dr["is_enable" + n.ToString()].ToString(), true, str);
                    }
                    sb.Append("},{");
                }
            }
            //對DataTable進行操作
            private string getDispatchTypeTree1(DataTable dt, string search)
            {
                string result = "";
                DataRow[] drc = dt.Select(search);
                if (drc.Length > 0)
                {
                    int layer = (dt.Columns.Count - 5) / 4;
                    List types = new List();
                    List nums = new List();
                    for (int n = 0; n < layer; n++) { types.Add(""); nums.Add(0); }
                    StringBuilder sb = new StringBuilder("{");
                    foreach (DataRow dr in drc)
                    {
                        getDispatchItem(layer, nums, types, dr, sb);
                    }
                    result = sb.ToString().TrimEnd('{');
                }
                return result;
            }

    四、對樹樁結構進行【增刪查改和移動操作】

    實現對葉子節點的相關操作

    1、增加葉子節點的操作

        --[dbo].[dispatch_GetType_Add] 'cn','525d9a53-bc37-5b9e-371a-8d76054cc2ef','0f39b6ba-0ad0-3fb8-df2d-9d187c69a4cb','049b50ab-bb57-9113-be36-34484409c2fb','新增节点'
        ALTER  proc [dbo].[dispatch_GetType_Add]
        (
          @language nvarchar(10),
          @pId nvarchar(50),
          @type_id nvarchar(50),
          @b_type_id nvarchar(50),
          @type_name nvarchar(200)
        )
        AS
        Begin Tran
     
         declare @sort int--子節點序號
         declare @layer int--子節點樹層
     
     
         --該節點如果為葉子節點,就改為非葉子(葉子節點滿足:dispatch_type_leaf有數據,並且is_show為true)
         if exists (select * from dispatch_type_config where [type_id]=@pId and is_leaf='1')
         begin
          select @sort=1,@layer=layer+1 from dispatch_type_config where [type_id]=@pId group by layer
          update dispatch_type_config set is_leaf='0' where [type_id]=@pId and is_leaf='1'--改為非葉子
          if exists (select * from dispatch_type_leaf where dispatch_rowid=@pId )--改為非葉子,將其節點數據先隱藏,當其子節點都刪除后,再還原
          begin
           update dispatch_type_leaf set is_show='0' where dispatch_rowid=@pId--改為非葉子
          end
         end
         else--非葉子節點才插入樹狀關係
         begin
          select @sort=count(*)+1,@layer=layer+1 from dispatch_type_config where [type_id]=@pId group by layer
          /****插入樹狀關係**********/
          insert into dispatch_type_config([type_id],b_type_id,type_name_cn,type_name_tw,type_name_en,sort,layer,is_leaf)
          select distinct [type_id],@type_id,type_name_cn,type_name_tw,type_name_en,sort,layer,is_leaf
          from dispatch_type_config where [type_id]=@pId
         end
     
         /****插入樹狀子節點**********/
         declare @type_name_cn nvarchar(200),@type_name_tw nvarchar(200),@type_name_en nvarchar(300)
         set @type_name_cn=@type_name+N'**修改**' set @type_name_tw=@type_name+N'**修改**' set @type_name_en=@type_name+N'**Modify**'
         if(@language='cn') set @type_name_cn=@type_name
         else if(@language='tw')set @type_name_tw=@type_name
         else if(@language='en') set @type_name_en=@type_name
         --插入樹狀子節點
         insert into dispatch_type_config(type_id,b_type_id,type_name_cn,type_name_tw,type_name_en,sort,layer,is_leaf)
         values(@type_id,@b_type_id,@type_name_cn,@type_name_tw,@type_name_en,@sort,@layer,'1')
         /******插入子節點對應的信息*****/
         --insert into dispatch_type_leaf(dispatch_rowid,ctrl_type,[subject],context,has_case,is_show)
         --values(@type_id,'common','','','0','1')
        If @@Error <> 0           
        Begin
         Rollback
         Return @@Error
        End    
        Commit Tran

    2、刪除樹樁節點的操作

        -- [dbo].[dispatch_GetType_Delete] '0fed864e-1227-f9ac-1df8-c64e84627d0c'
        ALTER  proc [dbo].[dispatch_GetType_Delete]
        (
          @type_id nvarchar(50)
        )
        AS
        Begin Tran
         declare @is_leaf bit
         select top 1 @is_leaf=is_leaf from  dispatch_type_config where [type_id]=@type_id
         --如果為葉子節點
         if(@is_leaf='1')
         begin
          --如果該發文類型從未被使用過,則刪除
          if not exists(select * from dbo.dispatch_info where dispatch_rowid=@type_id)
          begin
           /****刪除樹狀子節點**********/
           delete dispatch_type_config where [type_id]=@type_id
           /****刪除子節點**********/
           delete dispatch_type_leaf where dispatch_rowid=@type_id
       
           declare @pId nvarchar(50)
           select top 1 @pId=[type_id] from  dispatch_type_config where b_type_id=@type_id
           declare @num int
           select @num=count(*) from  dispatch_type_config where [type_id]=@pId
           if(@num>=2)
           begin
            /****父節點中仍有子節點,刪除樹狀關係**********/
            delete dispatch_type_config where b_type_id=@type_id
           end
           else
           begin
            /***父節點中沒有子節點,就將父節點改為葉子節點***/
            update dispatch_type_config set is_leaf='1' where [type_id]=@pId--改為葉子節點
            if exists (select * from dispatch_type_leaf where dispatch_rowid=@pId )--改為葉子節點,并還原其隱藏的數據
            begin
             update dispatch_type_leaf set is_show='1' where dispatch_rowid=@pId--改為葉子節點
            end
           end
          end
          else--否則將葉子節點隱藏
          begin
           update dispatch_type_leaf set is_show='0' where dispatch_rowid=@type_id
          end
         end
         else---父節點,則遞歸刪除其子節點
         begin
          declare @tmp_type_id nvarchar(50)
          declare _cursor cursor local for 
          select b_type_id from dbo.dispatch_type_config where [type_id]=@type_id
      
          open _cursor
          fetch next from _cursor into @tmp_type_id
          while @@FETCH_STATUS=0
          begin
           exec [dbo].[dispatch_GetType_Delete] @tmp_type_id
           fetch next from _cursor into @tmp_type_id
          end
          close _cursor
          deallocate _cursor
         end
        If @@Error <> 0           
        Begin
         Rollback
         Return @@Error
        End    
        Commit Tran

    3、查看樹樁節點的信息

        --[dbo].[dispatch_GetType_Item] '05b1077e-9e65-c6b1-0215-e961d3cb42f4'
        ALTER  proc [dbo].[dispatch_GetType_Item]
        (
          @type_id nvarchar(50)
        )
        AS
        Begin
         --該節點如果為葉子節點
         if exists (select * from dispatch_type_config where [type_id]=@type_id and is_leaf='1')
         begin
          select A.type_name_cn,A.type_name_en,A.type_name_tw,is_enable=isnull(A.is_enable,'1'),B.[subject],B.context,has_case=isnull(B.has_case,'0') 
          from dispatch_type_config A left join dispatch_type_leaf B on A.[type_id]=B.dispatch_rowid
          where A.[type_id]=@type_id
         end
         else
         begin
          select type_name_cn,type_name_en,type_name_tw,is_enable
          from dispatch_type_config
          where [type_id]=@type_id
         end
        end

    4、編輯樹樁節點的操作

        ALTER  proc [dbo].[dispatch_GetType_Update]
        (
          @type_id nvarchar(50),
          @is_enable bit,
          @type_name_cn nvarchar(200),
          @type_name_en nvarchar(200),
          @type_name_tw nvarchar(200),
          @has_case bit,
          @subject nvarchar(500),
          @content nvarchar(3000)
        )
        AS
        Begin Tran
         update dispatch_type_config 
         set type_name_cn=@type_name_cn,type_name_en=@type_name_en,type_name_tw=@type_name_tw,is_enable=@is_enable
         where [type_id]=@type_id 
     
         --該節點如果為葉子節點
         if exists (select * from dispatch_type_config where [type_id]=@type_id and is_leaf='1')
         begin
          if exists (select * from dispatch_type_leaf where dispatch_rowid=@type_id)
          begin
           update dispatch_type_leaf set [subject]=@subject,context=@content,has_case=@has_case
           where dispatch_rowid=@type_id
          end
          else
          begin
           insert into dispatch_type_leaf(dispatch_rowid,ctrl_type,[subject],context,has_case)
           values(@type_id,'common',@subject,@content,@has_case)
          end
         end
     
        If @@Error <> 0           
        Begin
         Rollback
         Return @@Error
        End    
        Commit Tran

    5、移動樹樁節點的操作

        ALTER  proc [dbo].[dispatch_GetType_Move]
        (
          @type_id nvarchar(50),
          @siblings_id nvarchar(50),
          @span int
        )
        AS
        Begin
         declare @sort int
         select @sort=sort from  dispatch_type_config where [type_id]=@type_id
     
         update dispatch_type_config set sort=@sort where [type_id]=@siblings_id
         update dispatch_type_config set sort=@sort+@span where [type_id]=@type_id
        End
  • 相关阅读:
    11. Container With Most Water
    9. Palindrome Number
    375. 猜数字大小 II leetcode java
    leetcode 72 编辑距离 JAVA
    73. 矩阵置零 leetcode JAVA
    快速排序 JAVA实现
    63. 不同路径 II leetcode JAVA
    重写(override)与重载(overload)
    62 不同路径 leetcode JAVA
    leetcode 56 合并区间 JAVA
  • 原文地址:https://www.cnblogs.com/MasterYao/p/4440844.html
Copyright © 2011-2022 走看看