有一项工作会每天多次插入和更新名为 ContactInfo
的表(有 2 列 - Id、EmailId
)。
什么是在此表上编写触发器以仅针对特定 Ids
恢复 EmailId
的好方法,只要那些 EmailIds
那些 ID 得到更新?
不要介意在触发器中对那些 Id
进行硬编码,因为列表大约有 40 个。
但特别担心触发器不会为每次更新都触发,因为更新一直在发生,并且不希望触发器导致资源问题。
附加信息:表有大约 60 万个条目,并在 Id 上建立索引。
总结:触发器是否有可能仅在列中的某些值更新时触发,而不是列上的任何更新。
最佳答案
您可能会考虑的另一种机制是添加另一个表,例如称为 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
- 这应该仍然非常有效)。
(但是请注意:恢复更改的触发器是邪恶的)
关于SQL Server Update 仅在其更新时触发并且仅针对列中的特定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8484864/