2011-12-13 47 views
1

有一定的作業會每天多次插入並更新名爲ContactInfo(具有2列 - Id, EmailId)的此表。SQL Server更新僅在其更新並且僅針對列中的特定值觸發時纔會觸發

什麼是寫在這張表來恢復該EmailId僅針對特定Ids,每當只有那些EmailIds那些ID的觸發得到更新的好方法?

不要介意在觸發硬編碼的Ids由於該表是約40

但特別關心觸發沒有觸發的每次更新,因爲更新發生的時間,並且不希望引發資源問題的觸發器。

附加信息:表具有約600k條目,並在Id上編入索引。

總結:觸發器是否可能在列中更新某些值時觸發,而不是列上的任何更新。

+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 - 這應該仍然非常有效)。

(但被警告,:即恢復的變化是邪惡的觸發器)

+0

非常聰明的解決方案。 +1 –

+0

偉大的解決方案。謝謝! – psam