或多或少都做过树状目录、产品分类之类的二级或三级菜单,如果遇到更多级的分类,就一般使用递归了。在程序中使用递归或多或少会增加一些性能上的开销。
之前我用asp.net在程序中实现过非递归的无限级分类目录,但考虑到移植性不强,就改成了存储过程,发出来大家共同研究一下,到目前为止,测试过程中还没发现问题,另外,代码方面没经过什么优化。
通常情况下,我们更多的操作是读取目录,所以,在下面的实现中,读取我们只需要一select语句就够了,不使用递归,理论上无限级~!
======================================================================
表结构:
表名:tb_column
表结构(所有字段非空):
column_id int 主键(注:非标识)
column_name nvarchar(50)分类名称
parent_id int 父分类id(默认值0)
column_path nvarchar(1000) 分类路径
column_depth int分类深度(默认值0)
column_order int排序(默认值0)
column_intro nvarchar(1000)分类说明
=============================================================
存储过程一:新建分类
create procedure sp_column_insert
(
@parent_id int,
@column_name nvarchar(50),
@column_intro nvarchar(1000)
)
as
declare @err as int
set @err=0
begin tran
--通过现有记录获取栏目id
declare @column_id as int
declare @column_depth as int
select @column_id = max(column_id) from tb_column
if @column_id is not null
set @column_id = @column_id+1
else
set @column_id = 1
--判断是否是顶级栏目,设置其column_path和column_order
declare @column_path as nvarchar(1000)
declare @column_order as int
if @parent_id = 0
begin
set @column_path =ltrim(str(@column_id))
select @column_order = max(column_order) from tb_column
if @column_order is not null
set @column_order = @column_order + 1
else --如果没有查询到记录,说明这是第一条记录
set @column_order = 1
--深度
set @column_depth = 1
end
else
begin
--获取父节点的路径和深度
select @column_path = column_path ,@column_depth = column_depth from tb_column where
column_id=@parent_id
if @column_path is null
begin
set @err = 1
goto theend
end
--获取同父节点下的最大序号
select @column_order = max(column_order) from tb_piccolumn where column_path like
''+@column_path+'%' or column_id = @parent_id
if @column_order is not null --如果序号存在,那么将该序号后的所有序号都加1
begin
--更新当前要插入节点后所有节点的序号
update tb_column set column_order = column_order +1 where column_order
>@column_order
--同父节点下的最大序号加上1,构成自己的序号
set @column_order = @column_order + 1
end
else
begin
set @err=1
goto theend
end
--父节点的路径加上自己的id号,构成自己的路径
set @column_path = @column_path + '' + ltrim(str(@column_id))
--深度
set @column_depth = @column_depth+1
end
insert into tb_column(column_id,column_name,parent_id,column_path,column_depth,column_order,column_intro)
values(@column_id,@column_name,@parent_id,@column_path,@column_depth,@column_order,@column_intro)
if @@error<>0
begin
set @err=1
goto theend
end
--更新当前记录之后的记录的order
--update tb_column set column_order = column_order+1 where column_order > @column_order
theend:
if @err=0
begin
commit tran
return @column_id
end
else
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器