Создание уникального отфильтрованного индекса для таблицы со сложными условиями в SQL Server с помощью триггеров

Обратите внимание на этот код:

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]

Проблема в том, что создание отфильтрованного индекса со сложным условием невозможно. и я получаю эту ошибку:

Incorrect syntax near the keyword 'LIKE'

Есть ли способ создать уникальность этих столбцов в SQL Server (например, с помощью TRIGGER?

Спасибо

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
716
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

От документация:

Filtered indexes are defined on one table and only support simple comparison operators. If you need a filter expression that references multiple tables or has complex logic, you should create a view.

Спасибо, но я ищу альтернативный способ имитировать эту функцию.

Arian 08.12.2018 11:06

@Arian Как вы представляете, как сделать LIKE уникальным? Подумайте об этом на минутку.

JohnyL 08.12.2018 11:09

Вы видите в моем индексе только один столбец? Просто посмотри на это на секунду

Arian 08.12.2018 11:13

На основе документация оператор LIKE не поддерживается. Отметьте эту часть

[comparison] ::=  
    column_name [comparison_op] constant  

[comparison_op] ::=  
    { IS | IS NOT | = | <> | != | > | >= | !> | < | <= | !< }  
Ответ принят как подходящий

В других ответах уже указывалось, что 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

Вместо того, чтобы выдавать ошибки, вы можете создать триггер ВМЕСТО. В этом случае триггер будет отвечать за фактическое сохранение данных в таблице. Вы можете решить вставить все строки, часть строк или ни одну из них, чтобы вызвать ошибку, или молча пропустить повторяющиеся значения и т. д.

Другие вопросы по теме