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

问题描述:

有一定的作业会每天多次插入并更新名为ContactInfo(具有2列 - Id, EmailId)的此表。SQL Server更新仅在其更新并且仅针对列中的特定值触发时才会触发

什么是写在这张表来恢复该EmailId仅针对特定Ids,每当只有那些EmailIds那些ID的触发得到更新的好方法?

不要介意在触发硬编码的Ids由于该表是约40

但特别关心触发没有触发的每次更新,因为更新发生的时间,并且不希望引发资源问题的触发器。

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

总结:触发器是否可能在列中更新某些值时触发,而不是列上的任何更新。

+0

一个写得很好的触发应该不会造成太大* *太多额外的开销(如果你是紧张的工作表现,你可能会失败其他原因很快)。但是无法过滤触发器。 –

您可能会考虑的一种替代机制是添加另一个表,称为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 - 这应该仍然非常有效)。

(但被警告,:即恢复的变化是邪恶的触发器)

+0

非常聪明的解决方案。 +1 –

+0

伟大的解决方案。谢谢! – psam