请教自连接表如何进行级联更新问题

tyrdh 2008-04-08 11:09:36
需求描述:
有如下一张可以体现树视图层次的自连接表Eps,各字段及含义为:
字段名 类型 含义
---------------------------------------
PID Int 标识
EpsName Varchar(40) 公司名称
ParentID Int 上级ID(引用PID,如果是顶级则等于本级标识本身)
EpsLevel Tinyint 级别(0-顶级,1..n)
Remark Varchar(100) 备注

数据举例(活动数据):
PID EpsName ParentID EpsLevel Remark
----------------------------------------------------------------
1 XX总公司A 1 0 NULL
2 XX总公司B 2 0 NULL
3 北京分公司 1 1 NULL
4 上海分公司 1 1 NULL
5 天津分公司 1 1 NULL
6 云南分公司 2 1 NULL
7 广州分公司 2 1 NULL
8 昆明办事处 6 2 NULL
9 大理办事处 6 2 NULL
...........................................................
...........................................................

说明:该表通过ParentID与PID来表示上下层关系,通过DeptLevel表示级别(深度).

在实际应用中,如果改变了ParentID则EpsLevel会发生相应的变化(指向该PID的EpsLevel加1),要求自动计算并更新所有引用PID的EpsLevel的级别,并要求在数据库端SQL中实现.

请问能不能够在一条SQL语句中实现,或者有没有好的方法可以实现上述需求?
...全文
125 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
yeqian123456 2008-10-22
  • 打赏
  • 举报
回复
test
xiaoliaoyun 2008-04-08
  • 打赏
  • 举报
回复

create table tb(PID int,EpsName varchar(10),ParentID int,EpsLevel int,Remark varchar(10))
insert into tb values(1,'XX总公司A' ,1,0,null)
insert into tb values(2,'XX总公司B' ,2,0,null)
insert into tb values(3,'北京分公司',1,1,null)
insert into tb values(4,'上海分公司',1,1,null)
insert into tb values(5,'天津分公司',1,1,null)
insert into tb values(6,'云南分公司',2,1,null)
insert into tb values(7,'广州分公司',2,1,null)
insert into tb values(8,'昆明办事处',6,2,null)
insert into tb values(9,'大理办事处',6,2,null)
go

--建立函数查找该PID下所有的子以及子对于PID的深度
create function f_cid(
@id int
)returns @re table(PID int,EpsLevel 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.PID,@l
from tb a inner join @re b on a.ParentID=b.PID
where b.EpsLevel = @l-1
and a.pid<>@id
end
return
end
go


declare @pid int
declare @parentid int
declare @EpsLevel int

-- 例如把8的parent改为2(@pid = 8,@parentid = 2)
set @pid = 8
set @parentid = 2

-- 查找parent的EpsLevel
select @EpsLevel = EpsLevel + 1
from tb
where pid = @parentid

-- update 前的数据
select * from tb

update a
set a.EpsLevel = @EpsLevel + b.EpsLevel
from tb a
inner join dbo.f_cid(@pid) b on a.pid = b.pid

-- update 后的数据
select * from tb

--可以直接查询某个节点的子节点和深度,下面得到节点1的所有子节点以及相对于节点1的深度
select * from dbo.f_cid(1)


--drop table tb
--drop function f_cid
tyrdh 2008-04-08
  • 打赏
  • 举报
回复
考虑了在存储过程中使用游标进行递归搜索的问题,试过了,但是不成功,报游标不能重复创建.
Sunny_tct 2008-04-08
  • 打赏
  • 举报
回复
好象要用存储过程
  • 打赏
  • 举报
回复
先给顶下,等会看看
tyrdh 2008-04-08
  • 打赏
  • 举报
回复
高手们帮帮忙啊?
pt1314917 2008-04-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 tyrdh 的回复:]
非常感谢二位,谢谢
[/Quote]

哦,我的答案错了吗?
tyrdh 2008-04-08
  • 打赏
  • 举报
回复
非常感谢二位,谢谢
pt1314917 2008-04-08
  • 打赏
  • 举报
回复

create table os(pid int,epsname varchar(50),parentid int,epslevel int,remark varchar(50) default null)
insert into os select 1,'XX总公司A',1,0,null
insert into os select 2,'XX总公司B',2,0,null
insert into os select 3,'北京分公司',1,1,null
insert into os select 4,'上海分公司',1,1,null
insert into os select 5,'天津分公司',1,1,null
insert into os select 6,'云南分公司',2,1,null
insert into os select 7,'广州分公司',2,1,null
insert into os select 8,'昆明办事处',6,2,null
insert into os select 9,'大理办事处',6,2,null



--创建增加、修改触发器
create trigger tri_os on os for update
as
select *,cast(' ' as varchar(50)) fullpath into #os from os
DECLARE @i int,@j int
set @i=0
set @j=1
select @i=max(parentid) from #os
while @j<=@i
begin
update #os set fullpath=ltrim(#os.parentid)+','+a.fullpath
from #os inner join #os a on #os.parentid=a.pid
where #os.parentid=@j and #os.epslevel>0
set @j=@j+1
end
update os set epslevel=len(b.fullpath)-len(replace(b.fullpath,',','')) from os a,#os b
where a.pid=b.pid
go

--修改
update os set parentid=2 where pid=8
--查看结果:
select * from os

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧