2011-07-20 4 views
2

これは私たちが持っているデータベーススキーマです。T-SQL 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テーブルに設定し、それがt_Rolesテーブルに更新されるためにRoleCombinationIdを得る。コンマで区切られたパーミッションのセットの値は、SPを通してパラメータで渡され、必要ならば、stated hereのようなテーブル値の関数でレコードセットにすることができます。

UPDATE: - ソートPermissionIdsカンマ区切り格納するt_RoleCombinationsにVARCHAR(最大)の列を作成する

-I思想。しかし、それはリレーショナルデータベースでは良くありません。

-私が考えることができる文は以下の通りです。しかし、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 
関連する問題