Запрос T-SQL для сопоставления набора ResultSet с набором строк в БД, Group By columnId - PullRequest
2 голосов
/ 20 июля 2011

Это схема базы данных, которую мы имеем.

DB Schema

t_RoleCombination - Это все возможные комбинации разрешений, которые может иметь роль.

t_Permissions_Hierarchy - Это обеспечивает права доступа. Например, если у роли есть разрешения на Create некоторого ресурса, она должна иметь права на Edit этого ресурса, а если она имеет разрешение на Edit, она должна иметь разрешение на View. У нас также есть разрешение Share, которое, если назначено, должно также обеспечивать разрешение View. Таким образом, если роль имеет разрешение Create, она также должна иметь разрешение View, но может не иметь разрешения Share. Из-за этой сложности мы не можем навязать иерархию в виде дерева, имея столбец ParentPermissionId в t_Permissions и поэтому имеем эту таблицу t_PermissionHierarchy.

t_RoleCombination_Permissions - это таблица сопоставления, которая фактически определяет все комбинации разрешений.

Пример данных t_Permissions таблицы

Sample Data of t_Permissions table

Пример данных t_PermissionsHierarchy Таблица

Sample data of t_PermissionsHierarchy table

Когда клиент обновляет Роль, на сервере я получаю набор разрешений, который мне нужно сопоставить с одним из набора в таблице t_RoleCombinations_Permissions, и получаю RoleCombinationId для его обновления в таблице t_Roles , Разделенное запятыми значение для набора разрешений передается в SP через параметр, и я могу сделать его набором записей с помощью функции с табличным значением, аналогичной указанной в , указанной здесь , если это необходимо.

UPDATE: -

-Я думал о создании столбца Varchar (Max) в t_RoleCombination для хранения разделенных запятыми отсортированных 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.

1 Ответ

0 голосов
/ 29 июля 2011

Я отвечаю на свой вопрос. Вот так я наконец и сделал.

Во всем приведенном ниже коде @permisionSet - это табличная переменная, в которую вставляются все разделенные запятыми permisionIds.

DECLARE @permissionSet TABLE (Id int, PermissionId bigint)

Так я сопоставляю набор разрешений с уже доступной комбинацией. Я получил эту идею от другого вопроса .

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