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

说明

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

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

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

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

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

存储过程

 

--******************************

-- 多级分类存储过程

-- 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







 

 

你可能感兴趣的:(MSSQL)