【问题标题】:Create unique filtered index on a table with complex conditions in SQL Server using Triggers使用触发器在 SQL Server 中具有复杂条件的表上创建唯一筛选索引
【发布时间】:2018-12-08 08:41:08
【问题描述】:

请考虑以下代码:

CREATE UNIQUE NONCLUSTERED INDEX [idx1] 
ON dbo.Table1 ([Year] ASC,
               [City] ASC,
               [Region] ASC,
               [Sequence] ASC)
WHERE [Region] IN (1, 20) 
  AND [City] NOT LIKE N'C_341%'
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

问题是,似乎不可能创建条件复杂的过滤索引。我得到这个错误:

关键字“LIKE”附近的语法不正确

有什么方法可以在 SQL Server 中的这些列上创建唯一性(例如使用TRIGGER

谢谢

【问题讨论】:

    标签: sql-server triggers sql-server-2014 sql-server-2016 filtered-index


    【解决方案1】:

    其他答案已经指出过滤索引不支持LIKE。因此,我将专注于强制唯一性的替代方法。是的,您可以使用触发器来执行此操作。您需要在插入之后和更新触发器之后定义。您必须在其中检查表的内容,记住使用此语句插入的行(它们可以不止一个)已经存在。如果检测到重复值,则回滚事务并引发错误。触发器的代码可能如下所示(假设 ID 是您的主键字段,这将允许我们识别新插入的记录):

    CREATE TRIGGER [FORCE_UNIQUENESS] on [dbo].[Table1]
    INSTEAD OF INSERT, UPDATE
    AS
    BEGIN
        if exists(select *
            from dbo.Table1 t
            inner join inserted i on
                i.[Year] = t.[Year] and 
                i.[City] = t.[City] and 
                i.[Region] = t.[Region] and 
                i.[Sequance] = t.[Sequance] and 
                t.ID <> i.ID
            where i.Region in (1, 20) and i.[City] NOT LIKE N'C_341%')
        begin
            ROLLBACK TRANSACTION
            RAISERROR('Duplicated values detected', 16, 1);
        end
    END
    

    您可以创建INSTEAD OF 触发器,而不是引发错误。在这种情况下,触发器将负责实际保存表中的数据。您可以决定插入所有行、部分行或不插入,以引发错误,或静默跳过重复值等。

    【讨论】:

      【解决方案2】:

      来自documentation

      过滤索引是在一张表上定义的,只支持简单的比较运算符。如果您需要一个引用多个表或具有复杂逻辑的过滤器表达式,您应该创建一个视图。

      【讨论】:

      • 谢谢,但我正在寻找一种替代方法来模拟此功能
      • @Arian 您如何想象通过 LIKE 提供独特性?想一想。
      • 您在我的索引中只看到一列吗?看看它一秒钟
      【解决方案3】:

      不支持基于documentation LIKE 运算符。检查这部分

      [comparison] ::=  
          column_name [comparison_op] constant  
      
      [comparison_op] ::=  
          { IS | IS NOT | = | <> | != | > | >= | !> | < | <= | !< }  
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-10
        • 1970-01-01
        • 1970-01-01
        • 2020-07-07
        • 1970-01-01
        相关资源
        最近更新 更多