• 共享一个数据库多级分类代码(MSSQL存储过程版)


    说明

    相信多级分类在任何一个信息系统中都会用到,网上也能找到很多版本,下面这个是基于MSSQL存储过程版的,

    手上还有VB跟C#版的,不过这几年数据库一直用MSSQL,编程语言却从VBScript到C#又到PB, 搞到现在这套分类代码分别用VB、C#、PB实现了一遍,浪费了不少时间,NND神马多数据库啊!!!哥被忽悠了。

    分类采用前缀编码的方式,编码使用字符串类型的,当然也有使用二进制实现的牛人^_^.

    表结构
    说明(表Category,ClassId,ClassName,Code 为分类相关字段,DataNum,Info等是根据具体情况额外增减)

    存储过程

    --******************************
    -- 多级分类存储过程
    -- WDFrog 2012-2-15
    -- http://wdfrog.cnblogs.com
    --******************************
    
    --******************************
    --数据表定义            
    --******************************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[Category]
    GO
    
    CREATE TABLE [dbo].[Category] (
    	[ClassID] [int] NOT NULL ,
    	[ClassName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
    	[Code] [nvarchar] (200) COLLATE Chinese_PRC_CI_AS NOT NULL ,
    	[DataNum] [int] NULL ,
    	
    	[Info] [nvarchar] (1000) COLLATE Chinese_PRC_CI_AS NULL 
    	
    ) ON [PRIMARY]
    GO
    
    ALTER TABLE [dbo].[Category] ADD 
    	CONSTRAINT [DF_Category_DataNum] DEFAULT (0) FOR [DataNum],
    	CONSTRAINT [PK_Category] PRIMARY KEY  CLUSTERED 
    	(
    		[ClassID]
    	)  ON [PRIMARY] 
    GO
    
    
    --*************************
    -- 添加分类存储过程
    --***************************
    
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_Add]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_Add]
    GO
    
    
    Create   Proc Category_Add
    @ClassName nvarchar(50),
    @DataNum int ,
    
    @Info nvarchar(1000),
    @ParentID int -- 0表示根类别
    As
    Declare @EditCode int
    Declare @StepLen int
    Declare @matchStr nvarchar(50)
    Declare @typeCode nvarchar(50)
    Declare @Code nvarchar(200)
    Declare @MyCode nvarchar(200)
    Declare @ParentCode nvarchar(200) 
    Declare @selfCode int
    Set @editCode=1
    Set @StepLen=4
    Set @matchStr=REPLICATE('_',@StepLen) --4个_
    set @typeCode=''
    Set @Code=''
    Set @MyCode=''
    Set @selfCode=0
    Set @ParentCode=''
    
    Select @ParentCode=Code From [Category] Where ClassID=@ParentID
    
    If(@editCode=1)
        Begin
            --获取子类中编号最大的Code,column.ParentCode + matchStr中
    	Select Top 1 @MyCode= Code From [Category] Where Code Like @ParentCode + @matchStr Order By Code DESC
    	If @@ROWCOUNT >0
    	    Begin
    		Set @selfCode=Cast(Right(@MyCode,@StepLen) As Int ) +1
    		Set @typeCode=Replicate('0',@StepLen-1) + Cast(@selfCode As nvarchar)
                    Set @typeCode=Right(@typeCode,@StepLen)
                    Set @typeCode=@ParentCode + @TypeCode
    	    End
    	Else
    	    Begin
    		Set @typeCode=@ParentCode +Replicate('0',@StepLen-1)+'1'
    	    End
        End
    Declare @ClassID int
    Set @ClassID=0
          --获取最大ClassID
          Select @ClassId=Max(ClassID) From [Category]
          If Not @ClassID Is Null
             Begin
               Set @ClassId=@ClassID +1
             End
          Else
             Begin
               Set @ClassID=1
             End 
    
     
          Insert into [Category]
                (ClassID,ClassName,Code,DataNum, Info)
          values
                (@ClassID,@ClassName,@typeCode,@DataNum, @Info)
                
          Select @ClassID As ClassID      
    Go
    
    
    --********************
    -- 修改分类存储过程
    --*********************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_Update]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_Update]
    GO
    
    Create   Proc Category_Update
    @ClassID int , --需要修改的ClassID
    @ClassName nvarchar(50),
    
    @Info nvarchar(1000),
    @ParentID int 
    As
    Declare @EditCode int
    Declare @StepLen int
    Declare @matchStr nvarchar(50)
    Declare @typeCode nvarchar(50)
    Declare @Code nvarchar(200)
    Declare @MyCode nvarchar(200)
    Declare @ParentCode nvarchar(200)
    Declare @selfCode int
    Set @editCode=0
    Set @StepLen=4
    Set @matchStr=REPLICATE('_',@StepLen) --4个_
    set @typeCode=''
    Set @Code=''
    Set @MyCode=''
    Set @selfCode=0
    Set @ParentCode=''
    
    
    Select @ParentCode=Code From [Category] Where ClassID=@ParentID
    Select @Code=Code From [Category] Where ClassID=@ClassID
    
    
    --修改原有类别
    --确定是否要修改Code字段
    --查看是否改变了直接父类别(上一级)
    If @ParentCode != Left(@code,len(@code)-@StepLen)
    	Begin
    	--过滤选择自己做为父类
    	If(@ParentCode !=@Code)
    	  Begin
    	    --过滤选择自己的子类为父类	
    	    If Len(@ParentCode) > Len(@Code)
    		Begin
    		   --因为 Len(@ParentCode) > Len(@Code) 所以可以Left(@ParentCode,Len(@Code))
    		   If Left(@ParentCode,Len(@Code)) != @Code --如果相等则为选择自己的子类为父类	
    			Begin
    			   Set @EditCode=1
    			End
    		End
    	    Else
    		Begin
    		    Set @EditCode=1
    		End	
    	  End
    	
    	End		
    
    
    If(@editCode=1)
        Begin
            --获取子类中编号最大的Code,column.ParentCode + matchStr中
    	Select Top 1 @MyCode= Code From [Category] Where Code Like @ParentCode + @matchStr Order By Code DESC
    	--是否有子类
    	If @@ROWCOUNT >0
    	    Begin
    		Set @selfCode=Cast(Right(@MyCode,@StepLen) As Int ) +1
    		Set @typeCode=Replicate('0',@StepLen-1) + Cast(@selfCode As nvarchar)
                    Set @typeCode=Right(@typeCode,@StepLen)
                    Set @typeCode=@ParentCode + @TypeCode
    	    End
    	Else --没有子类那么编号从1开始
    	    Begin
    		Set @typeCode=@ParentCode +Replicate('0',@StepLen-1)+'1'
    	    End
        End
    
    If (@editCode=1)
     Begin
       Update [Category] Set
        ClassName=@ClassName,Code=@typeCode, Info=@Info
       where ClassID=@ClassID
     End
    Else
     Begin
       Update [Category] Set
         ClassName=@ClassName, Info=@Info
       where ClassID=@ClassID     
     End
    ---修改子类编号(Code)
    If(@editCode=1)
       Begin
          Update [Category] Set
           Code=@typeCode + Right(Code,Len(Code)-Len(@Code))
          Where Code Like @Code + '%'  
       End
    	
    GO
    
    --************************************
    -- 删除一个分类,只允许删除没有子类的分类
    --************************************
    
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_Del]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_Del]
    GO
    
    Create    Proc Category_Del
    @ClassID int 
    As
    If (Select Count(ClassID) From[Category] Where Code Like(Select Code From [Category] Where ClassID=@ClassID)+'%' And ClassId <> @ClassId ) >0
        Begin
          RaisError ('不能删除带有子类的分类',16,1)
          Return
        End
    
    Declare @Code nvarchar(200)
    Declare @Value int
    Set @Value=0
    Select @Code=[Code],@Value=[DataNum] From [Category] Where [ClassID]=@ClassID
    Update [Category] Set [DataNum]=[DataNum] - @Value Where [ClassID] In( Select ClassID From [Category] Where Len(Code)<=Len(@Code) And Code=Left(@Code,Len(Code)))
    Delete From Category  Where ClassID=@ClassID  
    
    Go
    
    --**************************
    -- 根据编号获取一条分类记录
    --***************************
    
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_Select]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_Select]
    GO
    
    Create  PROCEDURE Category_Select
    	@ClassID int
    AS
    SELECT [ClassID],[ClassName],[Code],[DataNum], [Info]
    
    FROM [Category] 
    WHERE 
    	[ClassID]=@ClassID
    Go	
    
    
    --**************************
    -- 移动分类的排序
    --*******************************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_Move]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_Move]
    Go
    
    Create     Proc Category_Move
    @ClassID int,
    @IsUp bit=1
    As
    Declare @maskStr nvarchar(200)
    Declare @tempStr nvarchar(200)
    Declare @Code nvarchar(200)
    Set @Code=''
    Set @tempStr=''
    Select @Code=Code From [Category] Where ClassID=@ClassID
    Set @maskStr=REPLICATE(N'-',Len(@Code))
    If  @Code !='' And ( (Len(@Code) % 4) =0 )
       Begin
         If(@isUp=1)
           Begin
             If(Len(@Code) > 4)
               Begin
                 Select Top 1 @tempStr=Code From [Category] Where Len(Code)=Len(@Code) And Code < @Code And Left(Code,Len(Code)-4)=Left(@Code,Len(@Code)-4) Order By Code DESC
               End
             Else
               Begin
                 Select Top 1  @tempStr=Code From [Category] Where Len(Code)=Len(@Code) And Code < @Code  Order By Code DESC
               End
           End
         Else
           Begin
             If(Len(@Code) >4)
               Begin
    	     Select Top 1 @tempStr=Code	From [Category] Where Len(Code)=Len(@Code) And Code > @Code  And Left(Code,Len(Code)-4)=Left(@Code,Len(@Code)-4) Order By Code ASC
               End
             Else
               Begin
    	     Select Top 1 @tempStr=Code From [Category] Where Len(Code)=Len(@Code) And Code >@Code Order By	Code ASC
               End 
           End
       End
    -- //已经是最前(最后)
    If @tempStr Is Null Or RTrim(LTrim(@tempStr))=''
    Begin
     return 
    End
    
    Declare @CodeLen int
    Declare @MAXLEN int
    Set @CodeLen=Len(@Code)
    Set @MAXLEN=200
    --//设置目标类,以及目标类的子类为----0001(目标类)或----00010002(子类)为形式
    Update [Category] Set Code=@maskStr +Substring(code,@CodeLen +1,@MAXLEN) Where Left(code,@CodeLen)=@tempStr
    --//更新当前交换类(包括子类)Code为目标类Code
    Update [Category] Set Code=@tempStr +Substring(Code,@CodeLen+1,@MAXLEN) Where Left(code,@CodeLen)=@Code
    --//更新目标类(包括子类)Code为当前交换类Code
    Update [Category] Set Code=@Code +Substring(code,@CodeLen +1,@MAXLEN) Where Left(code,@CodeLen)=@maskStr
    
    Go
    
    --****************************
    --获取指定分类的父分类信息
    --*****************************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_QueryParent]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_QueryParent]
    Go
    
    Create   Proc Category_QueryParent
    @ClassID int
    As
    Declare @ClassCode nvarchar(200)
    Select @ClassCode=Code From [Category] Where ClassId=@ClassID
    Select ClassID,ClassName,Code, DataNum
           From [Category]
           Where  Len(Code)<=Len(@ClassCode)
           And Code = Left(@ClassCode,Len(Code))
           Order By Code 
           
           
    Go
    
    --******************************
    -- 获取整个分类目录
    --******************************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_Query]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_Query]
    Go
    
    Create Proc Category_Query
    As
    Select [ClassID],[ClassName],[Code], [DataNum] From [Category] Order By [Code]
    Go
    
    
    --*****************************
    --重置所有分类为根分类
    --*****************************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_Reset]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_Reset]
    Go
    
    Create  Proc Category_Reset
    As
    Declare @code nvarchar(200)
    Declare @i int
    Set @Code=''
    Set @i=1
    
    
    Declare Category_Cursor CURSOR For
    Select CODE From [Category]
    
    Open Category_Cursor
    Fetch  Next From Category_Cursor
    WHILE @@FETCH_STATUS=0
    Begin
     Set @Code=Replicate(N'0',4) +  Cast(@i as nvarchar)
     Set @Code=Right(@Code,4)
     Update [Category]  Set Code= @Code  WHERE Current Of Category_Cursor
     Set @i=@i+1
     Fetch Next From Category_Cursor
    End
    Close Category_Cursor
    DEALLOCATE Category_Cursor
    
    Go
    
    --*********************
    -- 获取指定分类的分类名称
    --************************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_SelectClassName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_SelectClassName]
    Go
    
    Create  Proc Category_SelectClassName
    @ClassID int
    AS
    Select [ClassName] From [Category] Where [ClassID]=@ClassID
    Go
    
    --********************
    -- 获取指定类的子类,并包括自身
    --*********************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_QueryChildren]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_QueryChildren]
    Go
    
    Create Proc Category_QueryChildren
    @ClassID int
    As
    Declare @Code nvarchar(200)
    Select @Code=[Code] From [Category] Where [ClassID]=@ClassID
    Select [ClassID],[ClassName],[Code], [DataNum]
      From [Category] Where Code Like @Code +'%' Order By Code      
      
    Go
    
    --**********************
    -- 获取一级分类列表
    --***********************
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category_QueryRoot]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[Category_QueryRoot]
    Go
    
    Create  Proc Category_QueryRoot
    AS
    Select [ClassID],[ClassName],[Code], [DataNum] From [Category] Where Len(Code)=4 Order By Code   
    
    Go
    
    
    
    
  • 相关阅读:
    握手挥手状态(转)
    牛客笔记
    Redis常见面试题
    SpringBoot整合Redis及Redis工具类撰写(转)
    Netty中FastThreadLocal源码分析(转)
    计算机网络各层涉及协议(转)
    计算机小网络小笔记
    数据库
    操作系统提供的接口
    可重入锁和不可重入锁
  • 原文地址:https://www.cnblogs.com/wdfrog/p/2353069.html
Copyright © 2020-2023  润新知