我正试图以一种我认为不能约束的方式强制执行表格的完整性......
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是有效期后的瞬间 这意味着以下两个时期都很好......
我可以在触发器中检查该规则。但是,当触发器确实发现非法插入/更新时,防止“非法”插入/更新发生的最佳方法是什么?
(如果插入包含两个有效记录和两个无效记录,我可以只停止两个无效记录吗?)
干杯,
DEMS。
修改
在我上面的情况下,使用函数的约束效果很好。但我从来没有弄清楚为什么RAISERROR在触发器版本中不起作用。
我认为这是因为触发器是一个AFTER触发器,我需要一个BEFORE触发器,但这似乎不是一个选项......
答案 0 :(得分: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 );
答案 1 :(得分:3)
不要从插入的表中删除记录......这是无声的失败。通往地狱的道路是在Partial Commits中铺平的。
您需要RAISERROR,这基本上是constraint的作用。
答案 2 :(得分:0)
提出错误。
答案 3 :(得分:0)
您的触发器可能会将“非法”记录的valid_from
和/或invlaid_from
DATETIME
修改为特殊值。随后的清理步骤可以识别“非法”记录。