共享一個數據庫多級分類代碼(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



 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM