您的位置:首页 > 其它

存储过程-树型结构遍历算法

2008-11-12 15:39 183 查看
CREATE FUNCTION FN_GetTopClass (@InputId int,@IdStr varchar(8000),@type int)

RETURNS Varchar(8000)
AS
BEGIN

Declare @TC_ID int,@TC_PID int

DECLARE TreeClass CURSOR local FOR
SELECT TC_Id,TC_PID
FROM TreeClass
where TC_ID=@InputId

OPEN TreeClass
FETCH NEXT FROM TreeClass
INTO @TC_ID,@TC_PID

WHILE @@FETCH_STATUS = 0
BEGIN
if @type=1
begin
if @IdStr<>'' select @IdStr=','+@IdStr
select @IdStr=''''+cast(@tC_ID as varchar)+''''+@IdStr
end
else
if @TC_PID=0 select @IdStr=cast(@tC_ID as varchar)

select @IdStr=dbo.FN_GetTopClass (@TC_PID,@IdStr,@type)

FETCH NEXT FROM TreeClass
INTO @tC_ID,@TC_PID

End

CLOSE TreeClass
DEALLOCATE TreeClass

Return @IdStr

END

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

例:
--得到ID为1的所有下层类别ID串
select dbo.fn_getsubclass(1,'')
--查询ID为1的所有下层记录
select * from treeclass where charindex(''''+cast(TC_id as varchar)+'''',dbo.fn_getsubclass(1,''))>0
--得到ID为10顶层ID
select dbo.fn_gettopclass(10,'',0)
--得到提供ID所在枝的所有ID
select dbo.fn_getsubclass(dbo.fn_gettopclass(10,'',0),'')
--得到当前ID到顶层的ID串
select dbo.fn_gettopclass(10,'',1)

前一镇,写了两个递归的树型结构处理函数: http://expert.csdn.net/Expert/topic/1343/1343007.xml?temp=.730694
后来有朋友提出32层以上嵌套的一个展BOM的实例,没有办法用递归实现,特想了个办法,实现32层以上树型结构的递归方法。现在特将以前的那个函数进行了改进,具体如下:

---------------------------------表及函数脚本

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TreeClass]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[TreeClass]
GO

CREATE TABLE [dbo].[TreeClass] (
[TC_id] [int] IDENTITY (1, 1) NOT NULL ,
[TC_PID] [int] NOT NULL ,
[TC_OtherTypeID] [varchar] (8000) COLLATE Chinese_PRC_CI_AS NULL ,
[TC_Name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[TreeClass] WITH NOCHECK ADD
CONSTRAINT [PK_TreeClass] PRIMARY KEY CLUSTERED
(
[TC_id]
) ON [PRIMARY]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FN_32GetSubClass]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[FN_32GetSubClass]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FN_32GetTopClass]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[FN_32GetTopClass]
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO

CREATE FUNCTION FN_32GetSubClass (@InputId int,@IdStr varchar(8000)='',@LevelCount int=-1)
/*
参数: @InputId,被搜索子类的ID
@IdStr,一个特殊参数,用于在递归中传数据,注意:调用函数时一定要传入‘’空值
@LevelCount 用于判断是不是递归调用的开始层
*/
RETURNS Varchar(8000)
AS
BEGIN

Declare @TC_ID int,@TC_PID int,@StartLevel int,@Id32 int

if @LevelCount=-1
begin
set @StartLevel=@@NESTLEVEL
set @LevelCount=@StartLevel
end
else
set @StartLevel=-1

If @IdStr='' Set @IdStr=''''+cast(@InputId as varchar)+''''

DECLARE TreeClass CURSOR local FOR --定义游标
SELECT TC_Id,TC_PID
FROM TreeClass
where TC_PID=@InputId

OPEN TreeClass
FETCH NEXT FROM TreeClass
INTO @TC_ID,@TC_PID

WHILE @@FETCH_STATUS = 0 --循环游标,即循环当前类的弟一级子类
BEGIN
select @IdStr=@IdStr+','+''''+cast(@tC_ID as varchar)+''''

if @@NESTLEVEL<32
set @IdStr=dbo.FN_32GetSubClass (@TC_ID,@IdStr,@LevelCount) --递归,自己调用自己。
else
set @IdStr='['+cast(@tC_ID as varchar)+']'+@IdStr

FETCH NEXT FROM TreeClass
INTO @tC_ID,@TC_PID

End

CLOSE TreeClass
DEALLOCATE TreeClass

while @StartLevel=@@NESTLEVEL and charindex(']',@IdStr)>0
begin
set @Id32=substring(@IdStr,2,charindex(']',@IdStr)-2)
set @IdStr=dbo.FN_32GetSubClass (@Id32,@IdStr,@LevelCount)
set @IdStr=replace(@IdStr,'['+cast(@Id32 as varchar)+']','')
end

Return @IdStr

END

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐