2017-09-21 224 views
1

我在SQL服務器上創建行級安全2014年只有在存在過濾器過濾器的情況下才可以使用過濾器過濾器?

它能夠丟棄過濾謂詞上我的客戶表是這樣的:

ALTER SECURITY POLICY rls.tenantAccessPolicy 
    DROP FILTER PREDICATE ON dbo.Client, 
    DROP BLOCK PREDICATE ON dbo.Client 
GO 

但是,如果我連續兩次執行該代碼,我有錯誤

「安全策略'rls.tenantAccessPolicy'在表'dbo.Client'上不包含謂詞。」

有沒有一種方法可以在DROP存在時才刪除它?

+0

你確定你正在使用' SQL Server 2014'而不是'SQL Server 2016'? – lad2025

+0

@ lad2025當我做「SELECT @@ VERSION」時,我得到了「Microsoft SQL Azure(RTM) - 12.0.2000.8 Aug 29 2017 13:06:11 Copyright(C)2017 Microsoft Corporation」,它似乎是從SQL Server 2014該網站:https://support.microsoft.com/en-ca/help/321185/how-to-determine-the-version--edition-and-update-level-of-sql-server-a – pikarie

回答

1

我找到了解決辦法!我需要使用動態SQL才能工作,因爲SECURITY POLICY關鍵字在SELECT之前執行,或者導致我的錯誤。

此代碼只檢查是否filter謂詞是存在的,但因爲我總是在同一時間加入filterblock,驗證,我無所謂:

IF EXISTS(SELECT 1 
      FROM sys.security_predicates sp 
      WHERE sp.predicate_type = 0 -- filter_predicate 
       AND OBJECT_ID('rls.tenantAccessPolicy') = sp.object_id 
       AND sp.target_object_id = OBJECT_ID('dbo.Client')) 
BEGIN 
    DECLARE @Sql NVARCHAR(MAX); 

    SET @Sql = N'ALTER SECURITY POLICY rls.tenantAccessPolicy 
       DROP FILTER PREDICATE ON dbo.Client, 
       DROP BLOCK PREDICATE ON dbo.Client' 

    EXECUTE sp_executesql @Sql 
END 
ELSE 
BEGIN 
    SET @Sql = N'ALTER SECURITY POLICY rls.tenantAccessPolicy 
       ADD FILTER PREDICATE rls.fn_tenantAccessPredicateWithSuperUser(CompanyID) ON dbo.Client, 
       ADD BLOCK PREDICATE rls.fn_tenantAccessPredicateWithSuperUser(CompanyID) ON dbo.Client' 

    EXECUTE sp_executesql @Sql 
END 
GO 
+0

很高興聽到你解決了它:) – lad2025

+0

@ lad2025感謝您的幫助!對此,我真的非常感激! – pikarie

2

我會使用的方法IF EXISTS和檢查sys.security_predicates元數據表:

IF EXISTS(SELECT 1 
      FROM sys.security_predicates sp 
      WHERE sp.predicate_type = 0 -- filter_predicate 
      AND OBJECT_ID('rls.tenantAccessPolicy') = sp.object_id 
      AND sp.target_object_id = OBJECT_ID('dbo.Client')) 
BEGIN  
    ALTER SECURITY POLICY rls.tenantAccessPolicy 
     DROP FILTER PREDICATE ON dbo.Client; 
END; 
GO 

IF EXISTS(SELECT 1 
      FROM sys.security_predicates sp 
      WHERE sp.predicate_type = 1 -- block_predicate 
      AND OBJECT_ID('rls.tenantAccessPolicy') = sp.object_id 
      AND sp.target_object_id = OBJECT_ID('dbo.Client')) 
BEGIN 
    ALTER SECURITY POLICY rls.tenantAccessPolicy 
     DROP BLOCK PREDICATE ON dbo.Client;  
END; 
GO 
+0

我仍然出現錯誤「安全策略'rls.tenantAccessPolicy'在表'dbo.Client'上不包含謂詞。」當我運行你的第一個腳本(一個去除FILTER PREDICATE)。我會試着玩一下,看看我能否找到解決方案。 – pikarie

+0

@pikarie我無權訪問SQL Server,因此我無法檢查它。我建議運行**'SELECT OBJECT_NAME(object_id),OBJECT_NAME(target_object_id)FROM sys.security_predicates)**以匹配條件。 – lad2025

+0

該變量都是正確的。我在DROP後添加了一個SELECT 1,我創建了一個ELSE語句並添加了一個SELECT 2,並且第二次在我的SELECT 1所在的位置運行時發生崩潰(這很奇怪,因爲當我評論ALTER,DROP時,結果是「2」,表示代碼通過ELSE) – pikarie