Триггер обновления SQL Server только при его обновлении и только для определенных значений в столбце - PullRequest
1 голос
/ 13 декабря 2011

Существует определенное задание, которое будет вставлять и обновлять эту таблицу с именем ContactInfo (с 2 столбцами - Id, EmailId) несколько раз в день.

Какой хороший способ написать триггер для этой таблицычтобы вернуть EmailId только для определенных Ids, когда обновляются только эти EmailIds для этих идентификаторов?

Не прочь жестко кодировать эти Ids в триггере, поскольку списококоло 40.

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

Дополнительная информация: таблица имеетоколо 600 тыс. записей и индексируется по идентификатору.

В итоге: возможно ли срабатывание триггера только при обновлении определенных значений в столбце, а не при обновлении в столбце.

1 Ответ

2 голосов
/ 13 декабря 2011

Один из альтернативных механизмов, который вы могли бы рассмотреть, - это добавить другую таблицу, скажем, LockedValues. Я немного не уверен из вашего повествования, к каким ценностям вы пытаетесь предотвратить изменения, но вот пример:

Таблица T, содержит два столбца, ID и Val:

create table T (
    ID int not null,
    Val int not null,
    constraint PK_T PRIMARY KEY (ID),
    constraint UK_T_Lockable UNIQUE (ID,Val)
)

И у нас есть 3 строки:

insert into T(ID,Val)
select 1,10 union all
select 2,20 union all
select 3,30

И мы хотим предотвратить изменение строки ID 2 в Val:

create table Locked_T (
    ID int not null,
    Val int not null,
    constraint UQ_Locked_T UNIQUE (ID,Val), --Only really need an index here
    constraint FK_Locked_T_T FOREIGN KEY (ID,Val) references T (ID,Val)
)
insert into Locked_T (ID,Val) select 2,20

И теперь, конечно, любое приложение, которое знает только о T, не сможет редактировать строку с помощью ID 2, но может свободно изменять строки 1 и 3.

Преимущество заключается в том, что принудительный код уже встроен в SQL Server, так что, вероятно, он достаточно эффективен. Вам не нужен уникальный ключ в Locked_T, но он должен быть проиндексирован, чтобы довольно быстро обнаружить, что значения отсутствуют.

Все это предполагает, что вы собирались написать триггер, который отклонил изменений, а не тот, который отменил изменений. Для этого вам все равно придется написать триггер (хотя я бы по-прежнему предлагал иметь эту отдельную таблицу, а затем написать свой триггер, чтобы выполнить внутреннее обновление, объединяющее inserted с Locked_T - что все еще должно быть достаточно эффективным) .

(Однако, будьте осторожны: триггеры, которые отменяют изменения, являются злом)

...