我想在存储过程中组合来自用户及其角色的特权。为此,我目前正在运行许多查询。第一个获得用户的角色。然后查询以获取每个角色的特权。然后进行查询以获取用户的特权。然后,我将它们全部与代码结合在一起。我希望能够从存储过程中完成所有这些工作。我以前从未使用过存储过程,所以不知道是否有可能。
希望该图将帮助您理解我的工作。
我开始写一个,但是还没写完呢。
CREATE PROCEDURE get_privileges
@userId INT
AS
SET NOCOUNT ON;
SELECT
role_id
FROM
user_role
INNER JOIN
role ON user_role.role_id = role.id
WHERE
user_id = @userId;
-- For each role
SELECT
privilege_id as id, name
FROM
role_privilege
INNER JOIN
privilege ON role_privilege.privilege_id = privilege.id
WHERE
role_id = ${roleId}
SELECT
privilege_id as id, name
FROM
user_privilege
INNER JOIN
privilege ON user_privilege.privilege_id = privilege.id
WHERE
user_id = @userId;
我需要做什么来完成该过程?
遍历第一次选择的结果。不知道该怎么做。
合并结果。发现可以通过创建一个临时表,然后将结果集从每个查询推送到该表来完成。有更好的方法吗?
示例:
用户表
+----+----------+
| id | username |
+----+----------+
| 1 | caleb |
+----+----------+
角色表
+------+----------+
| role | name |
+------+----------+
| 1 | admin |
| 2 | standard |
+------+----------+
特权表
+-----------+---------------+
| privilege | name |
+-----------+---------------+
| 1 | CREATE_USER |
| 2 | DELETE_USER |
| 3 | ADMIN_VIEW |
| 4 | STANDARD_VIEW |
| 5 | NOTHING |
+-----------+---------------+
user_privilege表
+---------+--------------+
| user_id | privilege_id |
+---------+--------------+
| 1 | 1 |
+---------+--------------+
user_role表
+---------+---------+
| user_id | role_id |
+---------+---------+
| 1 | 1 |
+---------+---------+
role_privilege表
+---------+--------------+
| role_id | privilege_id |
+---------+--------------+
| 1 | 2 |
| 1 | 3 |
| 2 | 4 |
+---------+--------------+
user_id = 1
的预期结果
+--------------+-------------+
| privilege_id | name |
+--------------+-------------+
| 1 | CREATE_USER |
| 2 | DELETE_USER |
| 3 | ADMIN_VIEW |
+--------------+-------------+
答案 0 :(得分:1)
边注:
看到了吗?没有跨行,可读性为+100。
可能的解决方案之一(几乎是从自然语言到SQL的翻译): 返回用户特权列表或任何用户角色特权列表中存在的特权列表:
select *
from privilege p
where exists(
select 1 from user_privilege up
where up.user_id = @user_id
and up.privilege_id = p.id
)
or exists(
select 1 from user_role ur
inner join role_privilege rp
on rp.role_id = ur.role_id
where ur.user_id = @user_id
and rp.privilege_id = p.id
)
未优化,但可以作为了解解决方案的良好起点。
答案 1 :(得分:0)
您可以尝试以下方法:
CREATE OR ALTER PROCEDURE get_user_privileges
@userId int
AS
BEGIN
SET NOCOUNT ON;
SELECT p.[id] AS [privilege_id], p.[name]
FROM [user] AS u
JOIN [user_role] AS ur ON ur.[user_id] = u.[id]
JOIN [role] AS r ON r.[id] = ur.[role_id]
JOIN [role_privilege] AS rp ON rp.[role_id] = r.[id]
JOIN [user_privilege] AS up ON up.[user_id] = u.[id]
JOIN [privilege] AS p ON p.[id] = up.[privilege_id]
WHERE u.[id] = @userId
GROUP BY p.[id], p.[name] ;
END ;
然后您可以按以下步骤执行此存储过程:
EXEC get_user_privileges @userId = 1
希望这会有所帮助。