【问题标题】:Check if Table exists in Predicate Filter in SQL Server检查 SQL Server 的谓词筛选器中是否存在表
【发布时间】:2022-01-13 08:41:45
【问题描述】:

我编写了一个安全策略,其中包含一个谓词过滤器以在 SQL Server 中应用行级安全性。但是,我只想在表存在于数据库中时应用过滤谓词。任何人都可以请我建议吗?以下是安全政策:

IF OBJECT_ID('s.policyName') IS NOT NULL
BEGIN
DROP SECURITY POLICY s.policyName
END
GO  
    CREATE SECURITY POLICY s.policyName 
    ADD  FILTER PREDICATE s.policyName(ColA) ON TableA
    WITH (STATE = ON)       
GO

我确实尝试在 Filter 谓词之前和之后添加 if 条件,但它不起作用。非常感谢任何帮助。

【问题讨论】:

  • 您需要使用仅在表存在时才执行的动态SQL。否则,当语句被解析并绑定到对象时,会出现错误,因为无法绑定到不存在的对象。
  • 您可以使用If (exists(select object_id from sys.security_policies where name = 'policyName')) 按名称检查现有的安全警察。

标签: sql sql-server row-level-security


【解决方案1】:

您是否只想在创建策略之前确保表(和列!)存在,而不是每次都对表进行策略检查?我不知道您是否可以删除具有与之关联的策略的表(如果必须是模式绑定的策略函数引用该表,您当然不能),但我认为如果人们可以删除表政策制定后有一个更大的问题。

IF EXISTS 
(
  SELECT 1 FROM sys.tables AS t
    INNER JOIN sys.columns AS c
    ON t.[object_id] = c.[object_id]
    WHERE t.name = N'TableA'
      -- AND t.[schema_id] = SCHEMA_ID(N's') -- 'dbo', 'other' ???
    AND c.name = N'ColA'
)
BEGIN
    CREATE SECURITY POLICY s.policyName 
    ADD  FILTER PREDICATE s.policyFunctionName(ColA) ON TableA
    WITH (STATE = ON);
END

当然,如果表不存在,您一开始就无法创建策略。它会失败:

消息 33268,级别 16,状态 1
找不到对象“TableA”,因为它不存在或您没有权限。

因此,您可以使用IF EXISTS 来获得良好的行为(您可以在ELSE 中添加一条友好的错误消息),或者您可以直接在TRY/CATCH 中进行包装并希望最好。

您可能还想确保函数 s.policyFunctionName 存在出于类似原因(当然您不能调用与函数相同的策略),或者让它失败。

【讨论】:

    【解决方案2】:

    SQL 检查表是否存在,为真则结果为 1,如果表不存在则结果为 0。例如:

    IF EXISTS ( USE TableA
                SELECT 1 
                FROM INFORMATION_SCHEMA.TABLES 
                WHERE TABLE_TYPE='VIEW' 
                AND TABLE_NAME='TableA') 
       SELECT 1 AS res ELSE SELECT 0 AS res;
      
    IF OBJECT_ID ('TableA.s.policyName') IS NOT NULL 
       SELECT 1 AS res ELSE SELECT 0 AS res;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      • 2010-09-13
      相关资源
      最近更新 更多