2011-07-20 29 views
2

這是我們擁有的數據庫模式。T-SQL Query將一組ResultSet與DB中的一組行相匹配,Group By columnId

DB Schema

t_RoleCombinations - 這些權限的所有可能的組合,一個角色可以有。

t_Permissions_Hierarchy - 這會強制執行權限。對於例如如果一個角色有權限Create某些資源,它應該有權限到Edit該資源,如果有權限到Edit它應該有權限到View。我們也有一個Share權限,如果被分配,還應該強制執行View權限。因此,如果角色具有Create權限,則該權限也應具有View,但可能沒有Share權限。由於這種複雜性,我們無法通過t_Permissions中的ParentPermissionId列以樹視圖的方式實施層次結構,這就是爲什麼具有此t_PermissionHierarchy表。

t_RoleCombinations_Permissions - 這是映射表,它實際上定義了所有權限組合。

t_Permissions表的樣本數據

Sample Data of t_Permissions table

t_PermissionsHierarchy

Sample data of t_PermissionsHierarchy table

當客戶端更新的作用,我得到一組服務器上的樣本數據我需要與t之一匹配的權限他在t_RoleCombinations_Permissions表中設置並得到RoleCombinationId它在t_Roles表中更新。在SP中通過參數傳遞逗號分隔的一組權限的逗號分隔值,並且如果需要,我可以通過類似於stated here的表值函數來記錄它。

UPDATE: -

-I在t_RoleCombinations創建VARCHAR(最大)列來存儲逗號分隔排序PermissionIds的思想。但這在關係數據庫中並不好。

- 我可以想到的聲明如下。但它不會工作,因爲IN操作員檢查邏輯OR而不是AND

SELECT RoleCombinationId from t_RoleCombinations_Permissions 
WHERE PermissionId in (1,2,3,4,5) -- my comma saperated permissions 
GROUP BY RoleCombinationId 
HAVING Count(*) = 5 -- number of permissions specified. 

回答

0

我在回答我自己的問題。這就是我最終做到的。

在下面的所有代碼中,@permisionSet是這個表變量,其中插入了所有逗號分隔的permisionIds。

DECLARE @permissionSet TABLE (Id int, PermissionId bigint) 

這就是我將權限集與已有組合相匹配的方式。我從another question得到了這個想法。

SELECT @roleCombinationId = ISNULL(match.RoleCombinationId,0) 
    FROM (
    SELECT RoleCombinationId 
    FROM t_RoleCombinations_Permissions 
    WHERE PermissionId IN (SELECT PermissionId FROM @permissionSet) 
    GROUP BY RoleCombinationId 
    HAVING COUNT(*) = @countt 
) AS match 
    INNER JOIN t_RoleCombinations_Permissions rcp ON match.RoleCombinationId = rcp.RoleCombinationId 
    GROUP BY match.RoleCombinationId 
    HAVING COUNT(*) = @countt 

這就是我如何根據t_PermissionHierarchy表中設置的層級限制來驗證一組權限。

--If given set of permissions are valid 
IF(
    NOT EXISTS(SELECT ph.PermissionId 
       FROM @permissionSet ps 
       INNER JOIN t_PermissionHierarchy ph ON ph.PermissionId = ps.PermissionId 
       WHERE ph.ShouldHavePermissionId NOT IN (SELECT PermissionId FROM @permissionSet) 
       ) 
    ) 
BEGIN 
    --Permission set is valid. Insert it in t_RoleCombination_Pemissions table 
END 

並找出哪些權限是必需的,但在設置中丟失。

WITH InvalidPerms AS (
    SELECT ph.PermissionId, ph.ShouldHavePermissionId 
    FROM @permissionSet ps 
    INNER JOIN t_PermissionHierarchy ph ON ph.PermissionId = ps.PermissionId 
    WHERE ph.ShouldHavePermissionId NOT IN (SELECT PermissionId FROM @permissionSet) 
    UNION ALL 
    SELECT phh.PermissionId, phh.ShouldHavePermissionId 
    FROM InvalidPerms ip 
    INNER JOIN t_PermissionHierarchy phh ON phh.PermissionId = ip.ShouldHavePermissionId 
    WHERE phh.ShouldHavePermissionId NOT IN (SELECT PermissionId FROM @permissionSet) 
) 
    SELECT ShouldHavePermissionId FROM InvalidPerms