我有一个遗留系统,它可以同时与多个数据库配合使用。假设他们是MASTER和SLAVE。
有用户组(层次结构)。每个组都有一个父组,父组可以拥有自己的父组等。
table MASTER.dbo.GROUPS:
GROUP_ID
PARENTGROUP_ID
NAME
可以将用户分配到不同的组。
table MASTER.dbo.LK_GROUPS:
GROUP_ID
USER_ID
有实体,每个实体都有所有者(一对多)。
table SLAVE.dbo.ENTITY_OWNERSHIP
ENTITY_ID
USER_ID (column has a bad name because it is GROUP_ID)
任务: 编写查询/函数/存储过程以仅选择用户有权访问的实体。应该可以使用解决方案作为sql查询的一部分,我无法修改。此外,应该可以使用2种模式:
所以我写了一个函数fn_checkUserRights:
create function fn_checkUserRights (@userId bigint, @entityId bigint, @compareMode int)
returns int
as
begin
declare @result int;
declare @count int;
if @compareMode = 1
begin
with groups_with_ancestors
as (
select GROUP_ID, PARENTGROUP_ID, NAME
from MASTER.dbo.GROUPS as GROUPS
where
GROUP_ID in (
select
GROUP_ID
from
MASTER.dbo.LK_GROUPS
where
USER_ID = @userId
)
union all
select
b.GROUP_ID, b.PARENTGROUP_ID, b.NAME
from
groups_with_ancestors a
inner join MASTER.dbo.GROUPS b on b.GROUP_ID = a.PARENTGROUP_ID
)
select @count = count(*) from (
select
ENTITY_OWNERSHIP.USER_ID as OWNER_ID
from
SLAVE.dbo.ENTITY_OWNERSHIP as ENTITY_OWNERSHIP
where
ENTITY_OWNERSHIP.ENTITY_ID = @entityId
except
select distinct GROUP_ID from groups_with_ancestors
) a
if @count > 0
set @result = 0
else
set @result = 1
end
else if @compareMode = 2
begin
with groups_with_ancestors
as (
select GROUP_ID, PARENTGROUP_ID, NAME
from MASTER.dbo.GROUPS as GROUPS
where GROUP_ID in (
select
GROUP_ID
from
MASTER.dbo.LK_GROUPS
where
USER_ID = @userId
)
union all
select
b.GROUP_ID, b.PARENTGROUP_ID, b.NAME
from
groups_with_ancestors a
inner join MASTER.dbo.GROUPS b on b.GROUP_ID = a.PARENTGROUP_ID
)
select @count = count(*) from (
select
ENTITY_OWNERSHIP.USER_ID as OWNER_ID
from
SLAVE.dbo.ENTITY_OWNERSHIP as ENTITY_OWNERSHIP
where
ENTITY_OWNERSHIP.ENTITY_ID = @entityId
intersect
select distinct GROUP_ID from groups_with_ancestors
) a
if @count > 0
set @result = 1
else
set @result = 0
end
return @result;
end;
使用示例:
select *
from
SLAVE.dbo.ENTITY_OWNERSHIP as owners
where
MASTER.dbo.fn_checkUserRights(10010, owners.ENTITY_ID, 1) = 1
但是有一些问题: