2009-01-09 32 views
1

我試圖強制執行的方式,我不認爲一個約束可...使用觸發器強制遵循約束

CREATE TABLE myData 
(
    id    INTEGER IDENTITY(1,1) NOT NULL, 
    fk_item_id  INTEGER    NOT NULL, 
    valid_from  DATETIME    NOT NULL, 
    invlaid_from DATETIME    NOT NULL 
) 

我想施加的約束是,應該有一個永遠誠信表是具有重疊日期的相同「fk_item_id」的任何條目。

注意:

invalid_from是緊接有效期之後的時刻。
這意味着下面的兩個時期都很好...

  • '2008年1月1 00:00' - > '2008年2月1 00:00'(全揚)
  • 「2008年2月1 00:00' - >'2008年3月1日00:00'(全部2月)

我可以在觸發器中檢查該規則。但是,當觸發器發現非法插入/更新時,防止「非法」插入/更新發生的最佳方法是什麼?

(如果插入包括兩個有效記錄和兩個無效的記錄,我能站就兩個無效的記錄?)

乾杯,
民主黨。

編輯:

在我前面有情況,使用功能的約束效果很好。但我從來沒有計算出爲什麼RAISERROR在觸發器版本中不起作用。

我認爲這是因爲觸發器是AFTER觸發器,而我需要一個BEFORE觸發器,但是,這並不似乎是一個選項...

回答

3

不能直接刪除插入(更新邏輯表引發錯誤),但看到下面

create table triggertest (id int null, val varchar(20)) 
Go 
create trigger after on [dbo].triggertest 
for Update 
as 
Begin 

    delete tt from triggertest tt inner join 
    inserted i on tt.id = i.id 
    where i.id = 9 

End 
GO 
insert into triggertest values (1,'x') 
insert into triggertest values (2,'y') 
Update triggertest set id = 9 where id = 2 
select * from triggertest 
1, x 

你也可以加入回源表,你不必去觸發路線,你也可以綁定檢查約束到函數的返回值

Alter table myData WITH NOCHECK add 
Constraint CHK_VALID CHECK (dbo.fx_CheckValid(id, valid_from , invalid_from) = 1); 
+0

+1爲約束 - > UDF,我已經完成了它,並像它的工作原理。 – 2009-10-14 17:24:08

0

發生錯誤。

+0

無法從插入的表中刪除... – MatBailie 2009-01-09 15:52:43

0

您的觸發器可能會將「非法」記錄的valid_from和/或invlaid_fromDATETIME修改爲特殊值。隨後的清理步驟可以識別「非法」記錄。

3

不要刪除插入表中的記錄......這是沉默失敗。部分委員會鋪平了道路。

您需要RAISERROR,這實際上是constraint會做的。

+0

RAISEERROR似乎並未實際停止插入的行... – MatBailie 2009-01-20 13:45:45