用户表:uid[用户ID],depid[所属部门ID]
部门表:depid[部门ID],pdepid[上级部门ID]函数:UidInDepSub(depid int,uid int) --判断uid是否属于depid[部门ID]或其下级部门ID。
结果:select * from news where dbo.UidInDepSub(depid,uid)>1 --可以用于select中判断,此处需要多层递归判断,层次不定。请问此函数应该怎么写?
部门表:depid[部门ID],pdepid[上级部门ID]函数:UidInDepSub(depid int,uid int) --判断uid是否属于depid[部门ID]或其下级部门ID。
结果:select * from news where dbo.UidInDepSub(depid,uid)>1 --可以用于select中判断,此处需要多层递归判断,层次不定。请问此函数应该怎么写?
返回0或1就行了。
select * from news where dbo.UidInDepSub(depid,uid)=1 --这里可以找出判断为true的记录即可。
select distinct depid, count(1) from 部门表 p,用户表 y where p.depid=y.depid and uid = @uid
and (depid= @depid or depid= @pdepid)
1、我需要写成函数用于判断。
2、需要“递归检查”是否属于depid的下级部门,这个部门是一颗无限级的树。
--根据你的要求,不判断其为上级部门的情况
create function search --返回值只有0和1 :为1 表示属于的情况
(
@depid int,
@uid int
)returns int
as
begin
declare @i int
declare @ts int
declare @ty int
set @i=0
if exists(select 1 from 用户表 where uid=@uid) --说明存在该员工
select @ts=depid from 用户表 where uid=@uid --取得该用户的部门ID
if @depid=@ts --判断部门ID 与传入的ID 是都相同
set @i=1
else
begin
--判断uid是否下级部门ID
if exists(select 1 from 部门表 where pdepid=@depid)
--判断你传入的部门ID是否存在下级部门
begin
select @ty=depid from 部门表 where pdepid=@depid
while @@rowcount<>0
begin
if @ty=@ts --判断下级部门ID是否等于员工的直接部门ID
begin
set @i=1
break
end
else
begin
set @depid=@ty
select @ty=depid from 部门表 where pdepid=@depid
end
end
end
end
return @i
end
我试运行了一下,以上代码还有一点问题。
当子部门有多个部门时判断错误。
CREATE TABLE [depart] (
[depid] [int] NOT NULL ,
[pdepid] [int] NULL ,
CONSTRAINT [PK_depart] PRIMARY KEY CLUSTERED
(
[depid]
) ON [PRIMARY] ,
CONSTRAINT [FK_depart_depart] FOREIGN KEY
(
[pdepid]
) REFERENCES [depart] (
[depid]
)
) ON [PRIMARY]--向depart加入数据
insert into depart values(1,null)--顶层的上级一定要为null
insert into depart values(2,1)
insert into depart values(3,1)
insert into depart values(4,2)
insert into depart values(5,2)
insert into depart values(6,3)
insert into depart values(7,4)
insert into depart values(8,4)
insert into depart values(9,5)
insert into depart values(10,6)
create function billfun(@departid int,@uid int)
returns int
as
begin
declare @temp int
SELECT @temp=pdepid
FROM dbo.depart
WHERE (depid = @uid)
if(@temp=@departid)
RETURN 1
if(@temp is null)
RETURN 0
RETURN (dbo.billfun(@departid,@temp))
end
select dbo.billfun(2,8)
--为1
select dbo.billfun(3,8)
--为0
------------------------
您还没有理解我的意思。
即:
1、一个部门有多个下级部门,每个下级部门又有多个下级部门,这颗树是无限级的。
2、每一个部门(不管他是部门还是子部门)中都有多个用户。
我需要一个函数来判断传入的用户是否属于传入的部门中或者其所有递归的子级部门中。
你试一下先:--根据你的要求,不判断其为上级部门的情况
create function search --返回值只有0和1 :为1 表示属于的情况
(
@depid int,
@uid int
)returns int
as
begin
declare @i int
declare @ts int
declare @ty int
declare @lvel int
declare @tb table(depid int,lvel int)
select @i=0,@lvel=1
if exists(select 1 from 用户表 where uid=@uid) --说明存在该员工
select @ts=depid from 用户表 where uid=@uid --取得该用户的部门ID
if @depid=@ts --判断部门ID 与传入的ID 是都相同
set @i=1
else
begin
--判断uid是否下级部门ID
if exists(select 1 from 部门表 where pdepid=@depid)
--判断你传入的部门ID是否存在下级部门
begin
insert @tb(depid,lvel) select depid,@lvel from 部门表 where pdepid=@depid
while @@rowcount<>0
begin
if exists(select 1 from @tb where depid=@ts and lvel=@lvel) --判断下级部门ID是否存在员工的直接部门ID
begin
set @i=1
break
end
else
begin
set @lvel=@lvel+1
insert @tb(depid,lvel) select depid,@lvel from 部门表
where pdepid in(select depid from @tb where lvel=@lvel-1)
end
end
end
end
return @i
end
加了个临时表处理!
我的程序用的是函数递归。在sqlserver2000中只能递归38层,如果你的层次多于38层这个函数就没办法了,但小于38层决对可以查询出来。
递归函数本身就是非常短的。
----------------------------------
首先非常感谢你的热情帮助。
你可以再仔细看看我上面的需求说明。
1、一个部门有多个下级部门,每个下级部门又有多个下级部门,这颗树是无限级的。
2、每一个部门(不管他是部门还是子部门)中都有多个用户。
我需要一个函数来判断传入的用户ID是否属于传入的部门中或者其所有递归的子级部门中。
至少我在上面你给出的例子中没有看到用户表的定义。在函数中却直接判断depid=uid?(部门ID=用户ID)?
---------------------------
太感谢了!
基本上可以了,只有一个小问题:
如果传入一个不存在的用户ID,和第一级的部门ID,会产生一个死循环,我再跟踪一下看是不是我的的数据结构的问题。
其实这个不算是问题,如果用户ID不存在,就直接返回0好了,我再调试一下,一会结贴。谢谢!