SQL Server: индекс «в основном уникальный» - PullRequest
4 голосов
/ 12 мая 2010

В таблице я хочу убедиться, что для ключа из пяти столбцов существуют только уникальные вейлы:

Timestamp Account RatingDate TripHistoryKey EventAction
========= ======= ========== ============== ===========
2010511   1234    2010511    1              INSERT
2010511   1234    2010511    4              INSERT
2010511   1234    2010511    7              INSERT
2010511   1234    2010511    1              INSERT   <---duplicate

Но я хочу, чтобы уникальное ограничение применялось только между строками, когда EventAction равно INSERT:

Timestamp Account RatingDate TripHistoryKey EventAction
========= ======= ========== ============== ===========
2010511   1234    2010511    1              INSERT
2010511   1234    2010511    1              UPDATE
2010511   1234    2010511    1              UPDATE   <---not duplicate
2010511   1234    2010511    1              UPDATE   <---not duplicate
2010511   1234    2010511    1              DELETE   <---not duplicate
2010511   1234    2010511    1              DELETE   <---not duplicate
2010511   1234    2010511    1              INSERT   <---DUPLICATE

возможно?

Ответы [ 4 ]

5 голосов
/ 12 мая 2010

Да

  • SQL Server 2008: использовать отфильтрованный индекс
  • SQL Server 2005: использовать триггер или индексированное представление

Edit:

2 голосов
/ 12 мая 2010

Что такое EventAction?

Я подозреваю, что у вас есть проблема с дизайном на работе, и что вы можете рассмотреть возможность создания таблицы / отношения для каждого типа EventAction. Это позволит вам создать уникальное ограничение для таблицы InsertEventAction, например.

Возможно, вы сможете предоставить бизнес-контекст для вашего вопроса.

Исходя из комментариев, ответ: Учитывая природу источника данных и операцию разбора, которую вы хотите реализовать, я думаю, gbn предложил ваши лучшие варианты.

Жаль, что исходная база данных не является также SQL Server, поскольку вы можете реализовать свой собственный механизм аудита с помощью триггеров. Такое решение может включать вашу логику «фильтра» в Trigger.

1 голос
/ 12 мая 2010

Я бы подумал сделать это с проверочным ограничением. Я не думаю, что традиционные уникальные ограничения будут работать.

0 голосов
/ 12 мая 2010

Это пример триггера «INSTEAD OF INSERT». EXISTS проверяет, существуют ли существующие строки с такими же значениями, но только когда EventAction имеет значение INSERT.

CREATE TRIGGER [dbo].[YourTriggerName] ON [dbo].[YourTableName] 
   INSTEAD OF INSERT
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
  SET NOCOUNT ON;

  IF NOT EXISTS (
    SELECT 1
    FROM [YourTableName] L
    INNER JOIN inserted I ON
           I.Timestamp = L.Timestamp
       AND I.Account = L.Account
       AND I.RatingDate = L.RatingDate
       AND I.TripHistoryKey = L.TripHistoryKey
       AND I.EventAction = 'INSERT'
  )
  BEGIN
      INSERT INTO [YourTableName]
      SELECT * FROM inserted
  END
END
...