Sql-Server

多條件 DAX 行過濾器

  • September 13, 2017

我正在嘗試將以下 SQL 行級安全功能轉換為表格模型中的 DAX 過濾器

CREATE FUNCTION [Security].[fn_securitypredicate](@BrandID AS INT, @ChannelId AS INT)  
   RETURNS TABLE  
WITH SCHEMABINDING  
AS  
   RETURN 
    (SELECT 1 AS fn_securitypredicate
           WHERE (EXISTS ( SELECT 1 FROM   security.RLSStaffBrand  WHERE StaffUsername = SYSTEM_USER AND BrandId = @BrandID)  
             AND  EXISTS ( SELECT 1 FROM   security.RLSStaffChannel WHERE StaffUsername = SYSTEM_USER  AND ChannelId = @ChannelID) )

              OR (        EXISTS (SELECT 1  FROM   security.RLSStaffBrand  WHERE StaffUsername = SYSTEM_USER  AND BrandId = @BrandID)  
                  AND NOT EXISTS ( SELECT 1  FROM   security.RLSStaffChannel WHERE StaffUsername = SYSTEM_USER ) )-- this user is not restricted by Channel

               OR (NOT EXISTS ( SELECT 1  FROM   security.RLSStaffBrand WHERE StaffUsername = SYSTEM_USER)          
                   AND EXISTS ( SELECT 1  FROM   security.RLSStaffChannel 

WHERE StaffUsername = SYSTEM_USER  AND ChannelId = @ChannelID) ) 

)
   GO

到目前為止,我有以下 DAX 過濾器,但這僅處理 SQL 程式碼中的第一個條件。我不知道是否可以在 DAX 中複製其餘部分。

='Brand'[BrandId]=LOOKUPVALUE('RLSStaffBrand'[BrandId], 'RLSStaffBrand'[StaffUsername], USERNAME(), 'RLSStaffBrand'[BrandId], 'Brand'[BrandId])

='Channel'[ChannelId]=LOOKUPVALUE('RLSStaffChannel'[ChannelId], 'RLSStaffChannel'[StaffUsername], USERNAME(), 'RLSStaffChannel'[ChannelId], 'Channel'[ChannelId]) 

不是您確切問題的答案,而是您可以在 RLS 實現中重用 SQL 邏輯,以使用允許的 (Username,BrandId) 對來具體化表格模型中的表,而不是將 SQL 轉換為 DAX 並在兩個地方維護它,並列舉了允許的 (Username,ChannelId) 對。

因此,編寫一個視圖並在表格模型中載入一個表,其中包含如下查詢的結果:

select s.BrandId,c.ChannelId,u.StaffUserName
from dbo.Brands b
cross join dbo.Channels c
cross join dbo.Staff s
cross apply   [Security].[fn_securitypredicate](s.BrandId,c.ChannelId,s.StaffUserName) sp
where sp.fn_securitypredicate = 1

它將列舉(BrandId、ChannelId、StaffUserName)的所有允許組合。然後通過在此表和品牌以及此表和頻道之間設置雙向交叉過濾,在 DAX 行過濾器中使用該新表。

大衛

引用自:https://dba.stackexchange.com/questions/185861