[原创]得到当前部门下所包括的子部门树
/** Table:公司部门信息 **/ Create Table tCore_Dept ( DeptID varchar(8) not null, DeptName varchar(80) not null, SuperiorDeptID varchar(8) not null, CONSTRAINT tCore_Dept_PK Primary Key(DeptID) ) go insert into tCore_Dept Values(''''A'''',''''A'''',''''Root'''') insert into tCore_Dept Values(''''B'''',''''B'''',''''Root'''') insert into tCore_Dept Values(''''C'''',''''C'''',''''Root'''')
insert into tCore_Dept Values(''''AA'''',''''AA'''',''''A'''') insert into tCore_Dept Values(''''AB'''',''''AB'''',''''A'''') insert into tCore_Dept Values(''''BA'''',''''BA'''',''''B'''') insert into tCore_Dept Values(''''ABA'''',''''ABA'''',''''AB'''') insert into tCore_Dept Values(''''ABAA'''',''''ABAA'''',''''ABA'''') /** Function:获取子部门 **/ Create Function GetNextDept (@dept varchar(8)) Returns Table WITH ENCRYPTION As Return ( select deptid, deptname, superiordeptid from tCore_Dept where superiordeptid = @dept ) go /** Function:获取子部门树 **/ Create Procedure GetNextDeptTree (@Child_node varchar(8)) WITH ENCRYPTION As begin SET NOCOUNT ON DECLARE @Cnt int Declare @i int Declare @tmpnode varchar(8) create table #stack (node varchar(8)) create table #stackTmp (node varchar(8)) create table #stackTmpXXX (node varchar(8)) insert into #stack select DeptID from GetNextDept(@Child_node) insert into #stackTmp select DeptID from GetNextDept(@Child_node) select @tmpnode = @Child_node select @Cnt = count(*) from tCore_Dept select @i = 0 loops: declare cur cursor for select node from #stackTmp open cur fetch next from cur into @tmpnode while @@FETCH_STATUS = 0 begin insert into #stack select DeptID from GetNextDept(@tmpnode) insert into #stackTmpXXX select DeptID from GetNextDept(@tmpnode) select @i = @i + 1 fetch next from cur into @tmpnode end CLOSE cur DEALLOCATE cur select @i = @i + 1 delete from #stackTmp insert into #stackTmp select node from #stackTmpXXX delete from #stackTmpXXX if (@i >= @Cnt * 1.5 ) goto ends goto loops ends: select node from #stack end go /* select * from tCore_Dept exec GetNextDeptTree ''''B'''' */ ---------------------------------- 后记 : 原想用存储过程的递归来实现子树的求取,但发现如果当前游标没有关闭,则递归调用中会发现无法创建新的游标,:( 没有想到存储过程的游标不支持递归,游标并不是重新建一个内存地址,而是沿用以前的那个游标。这算不算是一个bug. 同样对于树前要加----之类的 我想应该很简单了吧 ,在这里就不多废话了。 本算法的关键在于退出循环的条件,这里我用了一个计数器,但是末免会多运行好多次,这也是本算法的缺点所在,希望有人能得出最好的算法因子,即我存储过程中的 if (@i >= @Cnt * 1.5 ) goto ends 的那个1.5。:)好了就到这里。:) 原文及相关资料:http://www.whsdn.net/bbs/?p=thread&ForumID=4&ThreadID=388&Page=1&Location#4
---------------------------------------------- τ 认识你会不会是一种错误 如果这是个错误 也应该是个美丽的错误 但愿这个错误能够一辈子
______________ζ浮云¢惊龙
[互联动态]20008年最紧缺的IT人才和最热门七大技术 [其他]手工升级ACCESS到SQLSERVER方法详解 [Web开发]asp+sqlserver 分页方法(不用存储过程) [聊天工具]Office 2000 服务器扩展 [聊天工具]最cool的p2p软件——edonkey2000 [系统软件]八招秘籍保证Windows 2000安全 [系统软件]关于Windows2000Server的灾难恢复 [系统软件]活用Windows2000/XP/2003的故障恢复控制台 [系统软件]巧用Win2000/XP“管理工具”优化操作系统 [常用软件]office2000FAQ(三)
|