說明
相信多級分類在任何一個信息系統中都會用到,網上也能找到很多版本,下面這個是基於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