2017-02-12 4 views
1

У меня есть таблица безопасности в SQL, 2 столбца имеют значение, а столбцы могут указывать любую из следующих сведений, для каждого пользователя может существовать несколько записей Option L или D, значения в столбце value , если либо L, либо D укажут список Складок, к которым пользователь имеет доступ или нет, аналогичный All будет означать, что пользователь имеет доступ ко всем складам, и None не будет доступа к хранилищу.Несколько случаев, когда предложения

Option | Value 
--------------- 
A  | All 
N  | None 
L  | xyz (Allowed value) 
D  | xyz (Denied Value) 

Моя проблема в с ИНЕКЕ в SQL, мне нужно предоставление для всех 4 сценариев и до сих пор я только в состоянии резерва 3 из 4 сценариев, глядя на моей последней статье я нужно переключить между IN и NOT IN в зависимости от опции.

WHERE 
    (CASE WHEN (SELECT TOP(1) Value FROM [AllowDisallowNone] ('demo1', 'ARBranches')) = 'All' 
       THEN 'All' END != Branch 
    OR 
    CASE WHEN (SELECT TOP(1) Value FROM [AllowDisallowNone] ('demo1', 'ARBranches')) = 'None' 
       THEN 'None' END = Branch 
    OR 
    Branch IN (SELECT Value FROM [AllowDisallowNone] ('demo1', 'ARBranches'))) 

Есть ли какие-либо предложения о том, как сделать это более эффективным?

Хорошо еще некоторые детали на двух таблицах:

таблица безопасности выглядит следующим образом:

SELECT [Operator] 
,[Type] 
,[TypeOption] 
,[Value] 
FROM [_OperatorAccess] 
WHERE [Type] = 'ARBranches' 

безопасности данных таблицы:

Security Table results

Помните, что похож на TypeOption = A для список разрешенных филиалов, могут быть пользователи с TypeOption = D для списка отлученных отрубей чес.

Мне нужно отфильтровать мой запрос на таблицу филиалов, чтобы показать только те ветки, к которым пользователь имеет доступ. Если я разделить это в 4-х отдельных запросов было бы что-то вроде этого:

For TypeOption = A (All Records) 
Select Invoice, Branch, InvDate FROM Branches (No Where Clause necessary, because user have access to all Branches) 

For TypeOption = N (No Records) 
Select Invoice, Branch, InvDate FROM Branches WHERE Branch = '' (No Branches will be returned, becuase my Branch field cannot be null or empty.) 

For TypeOption = L (List of allowed branches) 
Select Invoice, Branch, InvDate FROM Branches WHERE Branch IN (Select Value FROM _OperatorAccess WHERE Operator = 'RWOL' AND Type = 'ARBranches') 

For TypeOption = D (List of denied branches) 
Select Invoice, Branch, InvDate FROM Branches WHERE Branch NOT IN (Select Value FROM _OperatorAccess WHERE Operator = 'RWOL' AND Type = 'ARBranches') 

Я надеюсь, больше смысла этого сделать в.

+0

вы могли бы опубликовать полный текст запроса, включая SELECT, блок? – andrews

+0

Не могли бы вы предоставить более подробную информацию, такую ​​как имя, схема и данные образца таблицы безопасности, код функции «AllowDisallowNone» (это функция, не так ли?) И случаи ожидаемых результатов запроса? – andrews

ответ

0

Измените подзапросы к EXISTS статье:

SELECT * 
FROM my_existing_query q 
WHERE EXISTS (

    SELECT 1 
    FROM [AllowDisallowNone] ('demo1', 'ARBranches') 
    WHERE 
    -- All warehouses permitted, or specific warehouse permitted 
     (Value = 'All' AND Option = 'A') 
    OR (Value = q.Branch AND Option = 'L') 

    -- Deny permissions should override Allow permissions 
    EXCEPT 

    SELECT 1 
    FROM [AllowDisallowNone] ('demo1', 'ARBranches') 
    WHERE 
    -- No warehouses permitted 
     (Value = 'None' AND Option = 'N') 
    OR (Value = q.Branch AND Option = 'D') 
) 
Смежные вопросы