SQL Server更新仅在其更新时触发,并且仅针对列中的特定值

时间:2011-12-13 05:45:46

标签: sql database performance sql-server-2008 triggers

有一项工作会每天多次插入和更新名为ContactInfo(包含2列 - Id, EmailId)的表格。

在这个表上写一个触发器的好方法是,只返回EmailId只针对特定Ids,只要这些ID的EmailIds更新?

不要介意在触发器中对Ids进行硬编码,因为列表大约是40。

但是特别关注触发器不会为每次更新触发,因为更新一直在发生,并且不希望触发器导致资源问题。

附加信息:表有大约600k个条目,并在Id上编入索引。

总结:只有在列中更新了某些值而没有对列进行任何更新时才能触发触发器。

1 个答案:

答案 0 :(得分:2)

您可能考虑的另一种替代机制是添加另一个表,称为LockedValues。我从你的叙述中有点不确定你试图阻止改变的价值观,但这里有一个例子:

T包含两列,IDVal

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上的唯一键,但应将其编入索引,以便快速检测到不存在值。

这一切都假定您要编写拒绝更改的触发器,而不是还原更改的触发器。为此,你仍然需要编写一个触发器(虽然我仍然建议使用这个单独的表,然后编写你的触发器以insertedLocked_T进行更新内部加入 - 这应该是非常有效率。)

(但请注意:恢复变化的触发器是邪恶的)