在SQL Server存储过程中组合查询

时间:2019-02-20 22:18:53

标签: sql-server stored-procedures

我想在存储过程中组合来自用户及其角色的特权。为此,我目前正在运行许多查询。第一个获得用户的角色。然后查询以获取每个角色的特权。然后进行查询以获取用户的特权。然后,我将它们全部与代码结合在一起。我希望能够从存储过程中完成所有这些工作。我以前从未使用过存储过程,所以不知道是否有可能。

The database structure

希望该图将帮助您理解我的工作。

我开始写一个,但是还没写完呢。

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;

我需要做什么来完成该过程?

  1. 遍历第一次选择的结果。不知道该怎么做。

  2. 合并结果。发现可以通过创建一个临时表,然后将结果集从每个查询推送到该表来完成。有更好的方法吗?


示例

用户表

+----+----------+
| 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  |
+--------------+-------------+

2 个答案:

答案 0 :(得分:1)

边注:

enter image description here

看到了吗?没有跨行,可读性为+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

希望这会有所帮助。

相关问题