作者: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字段,就不用存储过程了,直接用
数据库设计:
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 '路径%'
就可以了对的就做,做的就对