存储过程-树型结构遍历算法
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
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
相关文章推荐
- 一个连通图,采用邻接表作为存储结构,设计一个算法从顶点v出发的深度优化遍历的非递归过程
- 一个连通图,采用邻接表作为存储结构,设计一个算法从顶点v出发的深度优化遍历的非递归过程
- 数据结构与算法简记:按层次顺序遍历和存储二叉树
- 数据结构与算法6:二叉树的存储结构与遍历
- 一个高手写的递归遍历多层结构的存储过程(转载)
- 数据结构-二叉树的存储结构和遍历算法(四)
- SQL Server树型结构数据处理的存储过程
- SQL Server树型结构数据处理的存储过程 [摘自 Neo.Yan]
- 基于关系数据库系统链式存储的树型结构数据,求某结点下的子树所有结点算法(t-sql语言实现)
- SQLServer实现树型结构数据查询的存储过程,类似oracle的connect by
- (原创)基于关系数据库系统链式存储的树型结构数据,求某结点下的子树所有结点算法(t-sql语言实现)
- 通用分页存储过程算法【.net类实现】
- 2015-12-7 项目1—数据结构之自建算法库——图及其存储结构(邻接矩阵、邻接表)
- 将表中数据生成Insert into 结构的存储过程[已测试]
- 自己写的存储过程要记住一:(一个插入语句游标遍历数据替换关键字的过程)
- 折腾Oracle问题小菜记[分页存储过程/查询所有表、视图、存储过程/查询表、视图、存储过程字段结构与参数](三)
- 采用邻接表存储结构,编写一个判别无向图中任意给定的两个顶点之间是否存在一条长度为k的简单路径的算法。
- 09-数据结构_线性结构-离散存储-链表_插删伪算法
- Oracle存储过程完整结构讲解
- 用二叉链表存储的二叉树进行先序、中序和后序遍历的算法