• 数结构中,节点移动解决方案


    我的数据表结构如下:

      1 USE db
      2 GO
      3 
      4 /****** Object:  Table [dbo].[cx_Navigation]    Script Date: 10/23/2014 22:36:28 ******/
      5 SET ANSI_NULLS ON
      6 GO
      7 
      8 SET QUOTED_IDENTIFIER ON
      9 GO
     10 
     11 CREATE TABLE [dbo].[cx_Navigation](
     12     [ID] [int] NOT NULL,
     13     [NavType] [tinyint] NOT NULL,
     14     [Name] [nvarchar](64) NOT NULL,
     15     [Title] [nvarchar](128) NOT NULL,
     16     [SubTitle] [nvarchar](128) NOT NULL,
     17     [LinkUrl] [nvarchar](256) NOT NULL,
     18     [SortID] [int] NOT NULL,
     19     [IsLock] [bit] NOT NULL,
     20     [Remark] [nvarchar](512) NOT NULL,
     21     [ParentID] [int] NOT NULL,
     22     [ClassList] [nvarchar](512) NOT NULL,
     23     [ClassLayer] [int] NOT NULL,
     24     [ChannelID] [int] NOT NULL,
     25     [ActionType] [nvarchar](512) NOT NULL,
     26     [IsSystem] [bit] NOT NULL,
     27  CONSTRAINT [PK_cx_NAVIGATION] PRIMARY KEY CLUSTERED 
     28 (
     29     [ID] ASC
     30 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
     31 ) ON [PRIMARY]
     32 
     33 GO
     34 
     35 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'自增ID' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'ID'
     36 GO
     37 
     38 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'导航类别' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'NavType'
     39 GO
     40 
     41 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'导航ID' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'Name'
     42 GO
     43 
     44 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'标题' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'Title'
     45 GO
     46 
     47 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'副标题' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'SubTitle'
     48 GO
     49 
     50 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'链接地址' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'LinkUrl'
     51 GO
     52 
     53 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'排序数字' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'SortID'
     54 GO
     55 
     56 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否隐藏0显示1隐藏' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'IsLock'
     57 GO
     58 
     59 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'备注说明' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'Remark'
     60 GO
     61 
     62 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'所属父导航ID' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'ParentID'
     63 GO
     64 
     65 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'菜单ID列表(逗号分隔开)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'ClassList'
     66 GO
     67 
     68 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'导航深度' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'ClassLayer'
     69 GO
     70 
     71 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'所属频道ID' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'ChannelID'
     72 GO
     73 
     74 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'权限资源' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'ActionType'
     75 GO
     76 
     77 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'系统默认' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation', @level2type=N'COLUMN',@level2name=N'IsSystem'
     78 GO
     79 
     80 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'系统导航菜单' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cx_Navigation'
     81 GO
     82 
     83 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_NavType]  DEFAULT ((0)) FOR [NavType]
     84 GO
     85 
     86 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_Name]  DEFAULT ('') FOR [Name]
     87 GO
     88 
     89 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_Title]  DEFAULT ('') FOR [Title]
     90 GO
     91 
     92 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_SubTitle]  DEFAULT ('') FOR [SubTitle]
     93 GO
     94 
     95 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_LinkUrl]  DEFAULT ('') FOR [LinkUrl]
     96 GO
     97 
     98 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_SortID]  DEFAULT ((99)) FOR [SortID]
     99 GO
    100 
    101 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_IsLock]  DEFAULT ((0)) FOR [IsLock]
    102 GO
    103 
    104 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_Remark]  DEFAULT ('') FOR [Remark]
    105 GO
    106 
    107 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_ParentID]  DEFAULT ((0)) FOR [ParentID]
    108 GO
    109 
    110 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_ClassList]  DEFAULT ('') FOR [ClassList]
    111 GO
    112 
    113 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_ClassLayer]  DEFAULT ((1)) FOR [ClassLayer]
    114 GO
    115 
    116 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_ChannelID]  DEFAULT ((0)) FOR [ChannelID]
    117 GO
    118 
    119 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_ActionType]  DEFAULT ('') FOR [ActionType]
    120 GO
    121 
    122 ALTER TABLE [dbo].[cx_Navigation] ADD  CONSTRAINT [DF_cx_Navigation_IsSystem]  DEFAULT ((0)) FOR [IsSystem]
    123 GO

    如果节点移动采用代码实现比较简单,但效率就相当低了,需要访问数据库多次。

    于是我就想这采用数据库中使用递归的方式调用,结构问题出现了,在递归存储过程中不允许使用临时表。

    总结以上遇到的问题于是我有了一下的解决方案代码:

     1 USE DB
     2 GO
     3 /****** Object:  StoredProcedure [dbo].[cx_ModifyNavigation]    Script Date: 10/23/2014 22:42:08 ******/
     4 SET ANSI_NULLS ON
     5 GO
     6 SET QUOTED_IDENTIFIER ON
     7 GO
     8 -- =============================================
     9 -- Author:        tommy duan
    10 -- Create date: 2014-10-23
    11 -- Description:    编辑导航
    12 -- =============================================
    13 CREATE PROCEDURE [dbo].[cx_ModifyNavigation]
    14     -- Add the parameters for the stored procedure here
    15     @ID    int,
    16     @NavType    tinyint,
    17     @Name    nvarchar(64),
    18     @Title    nvarchar(128),
    19     @SubTitle    nvarchar(128),
    20     @LinkUrl    nvarchar(256),
    21     @SortID    int,
    22     @IsLock    bit,
    23     @Remark    nvarchar(512),
    24     @ParentID    int,
    25     @ClassList    nvarchar(512),
    26     @ClassLayer    int,
    27     @ChannelID    int,
    28     @ActionType    nvarchar(512),
    29     @IsSystem    bit
    30 AS
    31 BEGIN
    32     -- SET NOCOUNT ON added to prevent extra result sets from
    33     -- interfering with SELECT statements.
    34     SET NOCOUNT ON;
    35     
    36     
    37     -- 前提:自己不可以修改自己为自己的子节点。
    38     -- 当前节点被移到了自己的子节点下边(当前节点修改时,选中的父节点为自己之前的子节点)。
    39     Declare @SelectNodeWasChildNode int;
    40     Select @SelectNodeWasChildNode=COUNT(1) From cx_Navigation Where ClassList like '%,'+CAST(@ID as nvarchar(32))+',%' and ID=@ParentID;
    41     
    42     If @SelectNodeWasChildNode>0 
    43     Begin
    44         -- 查找旧父节点数据
    45         Declare @OldParentID int;    
    46         Declare @TempClassLayer int;
    47         Declare @TempClassList nvarchar(512);
    48         
    49         Set @TempClassLayer=1;
    50         Set @TempClassList=','+CAST(@ParentID as Nvarchar(32))+',';
    51         
    52         Select @OldParentID=ParentID From cx_Navigation Where ID=@ID;
    53         
    54         If @OldParentID>0 
    55         Begin
    56             Declare @OldClassLayer int;
    57             Declare @OldClassList nvarchar(32);
    58             
    59             Select @OldClassLayer=ClassLayer,@OldClassList=ClassList From cx_Navigation Where ID=@OldParentID;
    60             
    61             Set @TempClassLayer=@OldClassLayer+1;
    62             Set @TempClassList=@OldClassList+CAST(@ParentID as Nvarchar(32))+',';
    63         End
    64         
    65         -- 提升被选中作为父节点的节点
    66         Update cx_Navigation Set ParentID=@OldParentID,ClassList=@TempClassList,ClassLayer=@TempClassLayer
    67         Where ID=@ParentID;
    68         
    69         -- 提升被选中作为父节点的节点的所有子节点。
    70         Execute cx_ModifyNavigationChildren @ParentID;
    71     End
    72     
    73     -- 修改节点
    74     If @ParentID>0 
    75     Begin
    76         Select @ClassLayer=ClassLayer,@ClassList=ClassList From cx_Navigation Where ID=@ParentID;
    77         Set @ClassLayer=@ClassLayer+1;
    78         Set @ClassList=@ClassList+CAST(@ID as nvarchar(32))+',';
    79     End
    80     Else
    81     Begin
    82         Set @ClassLayer=1;
    83         Set @ClassList=','+CAST(@ID as Nvarchar(32))+',';
    84     End
    85     
    86     UPDATE [cx_Navigation]
    87         SET [NavType] = @NavType,[Name] = @Name,[Title] = @Title,[SubTitle] = @SubTitle,[LinkUrl] = @LinkUrl
    88           ,[SortID] = @SortID,[IsLock] = @IsLock,[Remark] = @Remark,[ParentID] = @ParentID,[ClassList] = @ClassList
    89           ,[ClassLayer] = @ClassLayer,[ChannelID] = @ChannelID,[ActionType] = @ActionType,[IsSystem] = @IsSystem
    90     WHERE ID=@ID;
    91     
    92     -- 修改自己的子节点
    93     Execute cx_ModifyNavigationChildren @ID;
    94 END
    递归函数还没有解决不支持临时表的问题,我这样写可能效率不高。
     1 USE DB
     2 GO
     3 /****** Object:  StoredProcedure [dbo].[cx_ModifyNavigationChildren]    Script Date: 10/23/2014 22:43:49 ******/
     4 SET ANSI_NULLS ON
     5 GO
     6 SET QUOTED_IDENTIFIER ON
     7 GO
     8 
     9 -- =============================================
    10 -- Author:        tommy duan
    11 -- Create date: 2014-10-23
    12 -- Description:    编辑导航
    13 -- =============================================
    14 CREATE PROCEDURE [dbo].[cx_ModifyNavigationChildren]
    15     -- Add the parameters for the stored procedure here
    16     @ParentID int
    17 AS
    18 Begin    
    19     -- 验证信息是否存在
    20     If Exists(SELECT ID From cx_Navigation Where ID=@ParentID)
    21     Begin
    22         Declare @ClassLayer int;
    23         Declare @ClassList nvarchar(512);
    24         
    25         -- 获取父节点信息
    26         SELECT @ClassLayer=ClassLayer,@ClassList=ClassList From cx_Navigation Where ID=@ParentID;
    27         
    28         -- 查找当前父节点在所有一级子节点,并修改他们的层次信息        
    29         Declare @TempClassLayer int;
    30         Declare @TempClassList nvarchar(512);
    31         Declare @MaxRowNumber int;
    32         Declare @Cursor int;
    33         Declare @ID int;
    34         Set @Cursor=0;
    35         SELECT @MaxRowNumber=Count(1) From 
    36         (
    37             SELECT ID,ROW_NUMBER()Over(Order By ID) as RowNumber From cx_Navigation Where ParentID=@ParentID
    38         ) As T10;
    39         
    40         While @Cursor<@MaxRowNumber
    41         Begin
    42             Set @Cursor=@Cursor+1;
    43             Select @ID= T10.ID From (
    44                 SELECT ID,ROW_NUMBER()Over(Order By ID) as RowNumber From cx_Navigation Where ParentID=@ParentID
    45             ) as T10 Where T10.RowNumber=@Cursor;
    46             If @ID IS NOT NULL 
    47             Begin                 
    48                 -- 修改子节点的ID列表及深度
    49                 Set @TempClassLayer=@ClassLayer+1;
    50                 Set @TempClassList=@ClassList+CAST(@ID as nvarchar(32))+',';
    51                 
    52                 Update cx_Navigation Set ClassLayer=@TempClassLayer,ClassList=@TempClassList Where ID=@ID;
    53 
    54                 -- 递归调用
    55                 Execute cx_ModifyNavigationChildren @ID;
    56             End
    57         End
    58     End        
    59 End

    还有其他什么解决方案吗?除了采用代码实现外。

  • 相关阅读:
    ARM处理器
    进程和线程通俗理解
    const与指针
    字符提取命令
    ThinkPHP之视图模版的使用
    ThinkPHP之MVC与URL访问
    ThinkPHP之项目搭建
    android之文件存储和读取
    cryptdb中wrapper.lua的分析
    cryptDB安装分析
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/4047084.html
Copyright © 2020-2023  润新知