Для проверки прав доступа пользователей удобно использовать представление UserTaskPermissions. Оно содержит две колонки – TaskID (номер задачи) и UserID (идентификатор пользователя). Каждая строчка в таблице означает, что у пользователя с идентификатором UserID есть доступ к задаче номер TaskID.
Для отбора задач, к которым у пользователя есть доступ, в запросе делается join с UserTaskPermissions.
Использование функции dbo.fn_UserTaskPermissions()
Вместо объединения UserTaskPermissions и таблицы Tasks эффективнее использовать функцию проверки прав пользователя dbo.fn_UserTaskPermissions(). Она имеет два аргумента: @UserID и @SubcatID. Функция возвращает все записи указанной категории, доступные указанному пользователю, и содержит все поля, которые есть в таблице Tasks.
Объединение результата dbo.fn_UserTaskPermissions() с Tasks
Поскольку все поля можно брать из результата функции, в большинстве случаев нет необходимости дополнительно связывать в запросе результат dbo.fn_UserTaskPermissions() с таблицей Tasks — это создает лишнюю нагрузку на процессор.
Если же в вашем запросе невозможно обойтись без связи с таблицей Tasks, а простой join с dbo.fn_UserTaskPermissions() начинает заметно тормозить даже на небольшой выборке, попробуйте следующие варианты:
1.Вместо прямого join с dbo.ваша_таблица по TaskID используйте конструкцию:
...
from dbo.ваша_таблица.TaskID
cross apply
(
select top 1 *
from dbo.fn_UserTaskPermissions(@UserID, @SubcatID) utp
where utp.TaskID = dbo.ваша_таблица.TaskID
) utp
...
Это заставит сервер применить проверку прав после отбора по dbo.ваша_таблица.
2.Добавьте в самый конец оператора option (force order).
Использование dbo.fn_UserTaskPermissions() для нескольких пользователей и/или категорий
Если вам нужно получить задачи, доступные N пользователям (например, с учетом заместителей), и/или задачи из M категорий, функцию dbo.fn_UserTaskPermissions() необходимо вызывать N*M раз.
Использование dbo.fn_UserTaskPermissions() для неопределенного количества категорий
Если количество категорий заранее не известно, тогда применение функции dbo.fn_UserTaskPermissions() становится не настолько эффективным, но все же возможным. В этом случае рекомендуется провести эксперимент: в качестве второго параметра передать null и проанализировать снижение производительности. Если снижение существенно, стоит отказаться от использования функции dbo.fn_UserTaskPermissions() и использовать join с представлением UserTaskPermissions.
Полезные ссылки