树形数据查询示例
--作者: 鄒建
if exists (select * from dbo.sysobjects where id = object_id(N'[tb]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [tb]
GO
--示例數據
create table [tb]([id] int identity(1,1),[pid] int,name varchar(20))
insert [tb] select 0,'中國'
union? all? select 0,'美國'
union? all? select 0,'加拿大'
union? all? select 1,'北京'
union? all? select 1,'上海'
union? all? select 1,'江蘇'
union? all? select 6,'蘇州'
union? all? select 7,'常熟'
union? all? select 6,'南京'
union? all? select 6,'無錫'
union? all? select 2,'紐約'
union? all? select 2,'舊金山'
go
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_cid]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_cid]
GO
/*--樹形數據處理
查詢指定id的所有子
--鄒建 2003-12(引用請保留此信息)--*/
/*--調用示例
--調用(查詢所有的子)
select a.*,層次=b.[level] from [tb] a,f_cid(2)b where a.[id]=b.[id]
--*/
create function f_cid(
@id int
)returns @re table([id] int,[level] int)
as
begin
declare @l int
set @l=0
insert @re select @id,@l
while @@rowcount>0
begin
set @l=@l+1
insert @re select a.[id],@l
from [tb] a,@re b
where a.[pid]=b.[id] and b.[level]=@l-1
end
/*--如果只顯示最明細的子(下面沒有子),則加上這個刪除
delete a from @re a
where exists(
select 1 from [tb] where [pid]=a.[id])
--*/
return
end
go
--調用(查詢所有的子)
select a.*,層次=b.[level] from [tb] a,f_cid(2)b where a.[id]=b.[id]
go
?
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_pid]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_pid]
GO
/*--樹形數據處理
查詢指定id的所有父
--鄒建 2003-12(引用請保留此信息)--*/
/*--調用示例
--調用(查詢所有的父)
select a.* from [tb] a,f_pid(7)b where a.[id]=b.[id]
--*/
create function f_pid(
@id int
)returns @re table([id] int,[level] int)
as
begin
declare @l int
set @l=0
insert @re select [pid],@l from [tb] where [id]=@id and [pid]<>0
while @@rowcount>0
begin
set @l=@l+1
insert @re select a.[pid],@l
from [tb] a,@re b
where a.[id]=b.[id] and b.[level]=@l-1 and a.[pid]<>0
end
return
end
go
--調用(查詢所有的父)
select a.* from [tb] a,f_pid(7)b where a.[id]=b.[id]
go
?
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_id]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_id]
GO
/*--樹形數據處理
級別及排序字段
--鄒建 2003-12(引用請保留此信息)--*/
/*--調用示例
--調用函數實現分級顯示
select replicate('-',b.[level]*4)+a.name
from [tb] a,f_id()b
where a.[id]=b.[id]
order by b.sid
--*/
create function f_id()
returns @re table([id] int,[level] int,sid varchar(8000))
as
begin
declare @l int
set @l=0
insert @re select [id],@l,right(10000+[id],4)
from [tb] where [pid]=0
while @@rowcount>0
begin
set @l=@l+1
insert @re select a.[id],@l,b.sid+right(10000+a.[id],4)
from [tb] a,@re b
where a.[pid]=b.[id] and b.[level]=@l-1
end
return
end
go
--調用函數實現分級顯示
select replicate('-',b.[level]*4)+a.name
from [tb] a,f_id()b
where a.[id]=b.[id]
order by b.sid
go
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_copyid]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_copyid]
GO
/*--樹形數據處理
將一個結點下的所有子復制到另一個結點下
目標結點下不能有子結點
--鄒建 2005-01(引用請保留此信息)--*/
/*--調用示例
--調用存儲過程實現復制
exec p_copyid 2,10
select * from [tb]
--*/
create proc p_copyid
@s_id int,--要復制的源結點
@d_id int--目標結點
as
if not exists(select * from [tb] where [id]=@d_id)
begin
raiserror(N'目標結點 "%d" 不存在!',1,16,@d_id)
return
end
declare @s nvarchar(4000)
select @s=N'create table #t([nid] int identity('
+rtrim(max([id])+1)--復制后的結點為表中最大的結點+1
+',1),[id] int,[pid] int,level int,[name] nvarchar(50))
declare @l int
set @l=0
insert #t([id],[pid],level,[name]) select [id],@d_id,@l,[name]
from [tb] where [pid]=@s_id
while @@rowcount>0
begin
set @l=@l+1
insert #t([id],[pid],level,[name])
select a.[id],b.nid,@l,a.[name]
from [tb] a,#t b
where a.[pid]=b.[id]
and b.level=@l-1
end
set identity_insert [tb] on
insert [tb]([id],[pid],[name])
select nid,[pid],[name] from #t
set identity_insert [tb] off'
from [tb]
exec sp_executesql @s
,N'@s_id int,@d_id int'
,@s_id,@d_id
go
--刪除測試
drop table [tb]
drop function f_cid
drop function f_pid
drop function f_id
drop proc p_copyid
go
轉載于:https://www.cnblogs.com/wgx1323/archive/2007/06/12/780274.html
總結
- 上一篇: “明白古所难”下一句是什么
- 下一篇: 求助:DataGrid加行号的问题