长期饭票

大家好,请喊我序员!
QQ:15838986
posts - 124, comments - 22, trackbacks - 0, articles - 0
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[转]多级分类的实现

Posted on 2012-06-26 17:38  Baode  阅读(719)  评论(0编辑  收藏
作者:Alex.Chan | 出处:博客园 | 2011/10/29 11:14:15 | 阅读28次                   
无论是互动性质的论坛系统还是CMS商城,多级的分类实现是必要的。写个简单的多级分类实现

数据库设计
ID (int)| Name(varchar(20))| ParentID(int)| Path(varchar(1000)

递归形式的数据库设计,Path主要是用来记录分类的路径,用于查找某一分类下的子孙分类等。

基本功能都用存储过程来实现
1.在某一节点下增加子节点

Create   PROCEDURE [DBO].[InsertCata]
(
   
@ParentID int,-- 父节点编号
    @CataName varchar(20),-- 节点名称
    @CataID int output -- 节点编号
)
AS

if not exists(select 1 from Catalog where ID = @ParentID)--如果不存在该父分类,则返回错误信息
    set @CataID = -2
else
   
begin
       
declare @pathLength  int --路径长度
        declare @path varchar(20) --该父节点下最后一个节点的路径
        select @path = max(Path) from Catalog  where parentID = @parentId --order by Path desc
        select @pathLength = len(@path)
       
print @pathLength
       
declare @newpath varchar(20)--新加节点的路径
        if @pathLength > 0 -- 该父类节点下已经存在有子类
                select @newpath = substring(@path,1,@pathLength -1)+CHAR(ASCII(REVERSE(@path))+1)
       
else
               
select @newpath = path + 'A' from Catalog where ID = @parentID
       
       
if len(@newpath) > 0
           
begin
               
insert into Catalog([Name],ParentID,Path) values(@CataName,@ParentID,@newpath)
               
select @CataID = scope_identity();
           
end
       
else
           
set @CataID = -1
   
end



GO

2.移动某一节点到另一个节点下面

-- 把某一分类下某个节点移动到另一个分类之下
Create   PROCEDURE [DBO].[ChangeCata]
(
   
@ParentID int,--新父节点
    @CataID int,--要移动的节点编号
    @CataPath varchar(20) output--新移动后的节点路径
)
AS

if not exists(select 1 from Catalog where ID = @ParentID)
   
set @CataPath = '' -- 如果新父节点不存在,则设置错误信息
else
   
begin

       
declare @oldParentID int -- 原来的父节点
        select @oldParentID = ParentID from Catalog where ID = @CataID
       
if @oldParentID = @ParentID -- 没有移动
            select @CataPath = path from Catalog where ID = @CataID
       
else
       
begin
           
           
declare @pathLength  int
           
declare @path varchar(20)
           
select @path = max(Path) from Catalog  where parentID =@parentId --order by Path desc
            select @pathLength = len(@path)
           
print @pathLength
           
declare @newpath varchar(20)-- 计算移动到新分类后的节点路径
            if @pathLength > 0 -- 已经存在该父类
                    select @newpath = substring(@path,1,@pathLength -1)+CHAR(ASCII(REVERSE(@path))+1)
           
else
                   
select @newpath = path + 'A' from Catalog where ID = @parentID
       
           
if len(@newpath) > 0
               
begin
                   
declare @oldPath varchar(20)-- 记录原来的节点路径
                    select @oldPath = Path from Catalog where ID = @CataID
                   
set @CataPath = @newpath;
                   
update Catalog set ParentID = @ParentID,Path = @newpath where ID = @CataID
                   
-- 替换子类的Path
                    update Catalog set Path = stuff(path,1,len(@oldPath),@CataPath) where Path like @oldPath+'%'
               
end
           
else
               
set @CataPath = ''
       
end
   
end


GO

3.查找某一节点由根节点到该节点的全路径(查询出一个表)

CREATE    PROCEDURE [DBO].[GetCataFullPath]
(
   
@ID int -- 需要获取的编号
)
AS
--定义临时
create table #temp(ID int,Name varchar(20),ParentID int,Path varchar(1000))
declare @parentID int --父节点的编号
set @parentID = @ID
while @parentID > 0
   
begin
       
--查询并插入临时表
        insert into #temp select * from Catalog where ID = @parentID
       
select @parentID = ParentID from Catalog where ID = @parentID
   
end

select * from #temp order by Path
drop table #temp


GO

4.查询某一节点下的所有子节点:
这个由于有了Path字段,就不用存储过程了,直接用
select * from Catalog where path like '路径%'
可以