我在Visual Studio 2005以及SQL Server 2005上使用C#ASP.NET。
目前我有一个项目要求我检查每个用户是否有他们可能拥有的任何冲突角色。
我有2个数据库。 Users
和ConflictingRoles
。以下是2个表格的结构:
在Users
中,我有2个唯一身份用户,每个用户有4个角色。
在ConflictingRoles
中,我有4行冲突角色。
James和Jennifer各有4个角色,每个角色互相矛盾。
我希望构建多个SQL查询,以检查每个用户拥有的每个角色是否与他们拥有的任何其他角色发生冲突。
我对该过程的概念有一个大概的了解,但我不确定如何使用多个SQL查询来描述这个想法:
1)一次一行,从用户 grep usr。 UserID
和 usr。 Role
strong> usr 表。
将 usr。 UserID
存储到临时变量tempUID
中,并使用 usr。 Role
的匹配值> cf。 Role
在 ConflictingRoles cf 表中。
2)如果 usr。 Role
与 cf。 Role
匹配,则grep cf。 {的值{1}}并浏览用户表ConflictingRole
usr中的所有 usr。 Role
。 {{1}匹配WHERE
。
如果 cf。 UserID
与用户tempUID
的 usr。 ConflictingRole
之间发现匹配/冲突,请插入< em> cf。 Role
, usr。 tempUID
和 user。 ConflictingRole
到一个单独的表中,结果
3)对每个用户拥有的所有角色以及所有用户重复此操作。
基本上是不允许用户拥有彼此冲突的两个角色。如果有,请将名称,角色和冲突列表存储在表格中。
这对我来说非常困惑,我不确定是否有更简单的方法来做到这一点。
如果没有,我想请求你们提供SQL查询的帮助,我将用上面的逻辑顺序形成这些查询。
Role
感谢您提前提供任何帮助。
答案 0 :(得分:1)
SELECT u1.UserID, MIN(u1.Role) AS Role, MAX(u2.Role) AS ConflictingRole
FROM Users AS u1
JOIN Users AS u2 ON u1.UserID = u2.UserID AND u1.Role <> u2.Role
JOIN ConflictingRoles AS cr ON cr.Role = u1.Role AND cr.ConflictingRole = u2.Role
Group By u1.UserID, MIN(u1.Role), MAX(u2.Role)
答案 1 :(得分:1)
第一种方法:
Insert into results(userID, role, conflictingRole)
Select distinct
U.UserId, U.role, C.conflictionRole
FROM
users U
inner join --join role with all conflicted roles
conflictingRoles C
on U.role = C.role
WHERE
--chech if user has conflicted role
exists (
select *
from Users U2
where U2.userId = U.userId and
U2.role = C.conflictionRole
)
答案 2 :(得分:0)
请注意,您的Users
表未完全规范化。建议:用户详细信息(UserId
,Name
)应位于“实体”表中,用户与其角色之间的关系应位于单独的“关系”表中。
您尚未发布架构的约束,但可能会在下面的代码U1.Role <> U2.Role
中将其更改为U1.Role < U2.Role
。可能最好咨询您的业务领域专家:
WITH Users
AS
(
SELECT *
FROM (
VALUES ('R001', 'James', 'ISP001'),
('R001', 'James', 'ISP002'),
('R001', 'James', 'OSF001'),
('R001', 'James', 'OSF002'),
('P005', 'Jennifer', 'JEP001'),
('P005', 'Jennifer', 'JEP002'),
('P005', 'Jennifer', 'FGA001'),
('P005', 'Jennifer', 'FGA002'),
('S055', 'OneDayWhen', 'ISP001'),
('S055', 'OneDayWhen', 'OSF001'),
('S055', 'OneDayWhen', 'FGA001')
) AS T (UserID, Name, Role)
),
ConflictingRoles AS
(
SELECT *
FROM (
VALUES ('ISP001', 'ISP002'),
('OSF001', 'OSF002'),
('JEP001', 'JEP002'),
('FGA001', 'FGA002')
) AS T (Role, ConflictingRole)
),
PotentiallyConflictingRoles
AS
(
SELECT U1.UserID, U1.Role, U2.Role AS PotentiallyConflictingRole
FROM Users U1
JOIN Users U2
ON U1.UserID = U2.UserID
AND U1.Role <> U2.Role
)
SELECT *
FROM PotentiallyConflictingRoles P1
WHERE EXISTS (
SELECT *
FROM ConflictingRoles C1
WHERE C1.Role = P1.Role
AND C1.ConflictingRole = P1.PotentiallyConflictingRole
);