SQL 关于tree存储及提取的话题

本文介绍了一种在MSSQL中实现树形结构的方法,包括存储、查询及遍历等功能。通过创建一系列存储过程和函数来实现节点的名称、路径等信息的获取,并演示了如何构建子树及获取叶子节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

-- 总结关于tree在mssql中的存储、查询相关代码了。
set nocount on
go
create table bom (
     code 
char(16not null primary key
    ,parentcode 
char(16)
    ,name 
varchar(32)
    ,description 
varchar(512)
)
go
-- 指定代码的名称
create function dbo.fn_nameofcode (@code char(16))
returns varchar(32)
as begin
    
return isnull((select name from bom where code=@code),'')
end
go
-- 指定代码的上级代码
create function dbo.fn_parentcode (@code char(16))
returns char(16)
as begin
    
return isnull((select parentcode from bom where code=@code),'')
end
go
-- 指定代码的顶级代码
create function dbo.fn_topcode (@code char(16))
returns char(16)
as begin
    
declare @pcode char(16)
    
set @pcode=dbo.fn_parentcode(@code)
    
while @pcode > ''
    
begin
        
set @code=@pcode
        
set @pcode=dbo.fn_parentcode(@code)
    
end
    
return @code
end
go
-- 指定代码的路径代码
create function dbo.fn_codepath (@code char(16))
returns varchar(512)
as begin
    
declare @pcode char(16), @codepath varchar(512)
    
set @codepath=ltrim(rtrim(@code))
    
set @pcode=dbo.fn_parentcode(@code)
    
while @pcode > ''
    
begin
        
set @code=@pcode
        
set @codepath=ltrim(rtrim(@code))+'/'+@codepath
        
set @pcode=dbo.fn_parentcode(@code)
    
end
    
return @codepath
end
go
-- 指定代码的路径名称
create function dbo.fn_codenamepath (@code char(16))
returns varchar(512)
as begin
    
declare @pcode char(16), @namepath varchar(512)
    
set @namepath=dbo.fn_nameofcode(ltrim(rtrim(@code)))
    
set @pcode=dbo.fn_parentcode(@code)
    
while @pcode > ''
    
begin
        
set @code=@pcode
        
set @namepath=dbo.fn_nameofcode(ltrim(rtrim(@code)))+'/'+@namepath
        
set @pcode=dbo.fn_parentcode(@code)
    
end
    
return @namepath
end
go
-- 指定代码的所有下级条目
create function dbo.fn_subtreeofcode (@code char(16))
returns @subtree table (
     code 
char(16)
    ,parentcode 
char(16)
    ,codepath 
varchar(512)
    ,name 
varchar(32)
    ,description 
varchar(512)
    )
as begin
    
insert into @subtree 
    
select code, parentcode, codepath=dbo.fn_codepath(code), name, description
    
from bom
    
where parentcode=@code 
    
while @@rowcount>0
    
begin 
        
insert into @subtree 
        
select code, parentcode, codepath=dbo.fn_codepath(code), name, description
        
from bom a
        
where exists (select 1 from @subtree b where a.parentcode=b.code)
        
and not exists (select 1 from @subtree b where b.code=a.code)
    
end  return
end
go
-- 指定代码的所有叶子
create function dbo.fn_leafeofcode (@code char(16))
returns @subtree table (
     code 
char(16)
    ,parentcode 
char(16)
    ,codepath 
varchar(512)
    ,name 
varchar(32)
    ,description 
varchar(512)
    )
as begin
    
insert into @subtree 
    
select code, parentcode, codepath=dbo.fn_codepath(code), name, description
    
from bom
    
where parentcode=@code 
    
while @@rowcount>0
    
begin 
        
insert into @subtree 
        
select code, parentcode, codepath=dbo.fn_codepath(code), name, description
        
from bom a
        
where exists (select 1 from @subtree b where a.parentcode=b.code)
        
and not exists (select 1 from @subtree b where b.code=a.code)
    
end
    
-- 删除所有存在下级条目的条目
    delete from @subtree a
    
where exists(select 1 from @subtree b
        
where b.parentcode=a.code)
    
return
end
go

/**//* 一个例子,源自《这样的数据结构怎样设计TABLE最优》
 * http://topic.youkuaiyun.com/u/20080419/13/3b181995-cbf1-4ab6-9101-90caf3953fd0.html
 
*/

-- 一级物料: 一级编号,一级物料名称,一级描述
insert into bom values ('A','','一种一级物料','物料A的描述')
insert into bom values ('B','','另一种一级物料','物料B的描述')

-- 二级物料:二级编号,二级物料名称,一级物料名称,二级描述
insert into bom values ('A01','A','二级物料','物料A01的描述')
insert into bom values ('A02','A','二级物料','物料A02的描述')
insert into bom values ('B01','B','二级物料','物料B01的描述')
insert into bom values ('B02','B','二级物料','物料B01的描述')

-- 三级物料:三级编号,三级料物名称,一级物料名称,二级物料名称,三级描述
insert into bom values ('B01-1','B01','三级物料','物料B01-1的描述')
insert into bom values ('B01-2','B01','三级物料','物料B01-2的描述')
insert into bom values ('B02-1','B02','三级物料','物料B02-1的描述')

-- 四级物料:四级编号,四级物料名称,一级物料名称,二级物料名称,三级物料名称,四级描述
insert into bom values ('B01-1.023','B01-1','四级物料','物料B01-1.023的描述')
insert into bom values ('B01-1.219','B01-1','四级物料','物料B01-1.219的描述')
insert into bom values ('B01-1.328','B01-1','四级物料','物料B01-1.328的描述')
insert into bom values ('B01-2.012','B01-2','四级物料','物料B01-2.012的描述')
go

select root = dbo.fn_topcode(code), path=dbo.fn_codepath(code), [|]='|'*
from bom

select *, namepath=dbo.fn_codenamepath(code)
from dbo.fn_subtreeofcode('B01')
order by codepath
go

drop function dbo.fn_nameofcode, dbo.fn_parentcode, dbo.fn_topcode, dbo.fn_codepath, dbo.fn_codenamepath
drop function dbo.fn_subtreeofcode
drop table bom
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值