我有一张简化了的桌子,看起来像这样:
create table Test
(
ValidFrom date not null,
ValidTo date not null,
check (ValidTo > ValidFrom)
)
我想编写一个触发器,以防止插入与现有日期范围重叠的值。我写了一个这样的触发器:
create trigger Trigger_Test
on Test
for insert
as
begin
if exists(
select *
from Test t
join inserted i
on ((i.ValidTo >= t.ValidFrom) and (i.ValidFrom <= t.ValidTo))
)
begin
raiserror (N'Overlapping range.', 16, 1);
rollback transaction;
return
end;
end
但它不起作用,因为我新插入的记录是这两个表的一部分
试验
和
插入
在扳机里。因此,插入表中的新记录总是在测试表中连接到自身。触发器将始终恢复转换。
我无法区分新记录和现有记录。所以如果排除相同的日期范围,我就可以在表中插入多个完全相同的范围。
主要问题是
是否可以在不向测试表中添加额外的标识列的情况下编写一个可以按预期工作的触发器,以便将新插入的记录从
exists()
陈述如下:
create trigger Trigger_Test
on Test
for insert
as
begin
if exists(
select *
from Test t
join inserted i
on (
i.ID <> t.ID and /* exclude myself out */
i.ValidTo >= t.ValidFrom and i.ValidFrom <=t.ValidTo
)
)
begin
raiserror (N'Overlapping range.', 16, 1);
rollback transaction;
return
end;
end
重要
如果
没有身份是不可能的
是唯一的答案,我欢迎你提出一个合理的解释为什么。