我有一个简化后的表格,看起来像这样:
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
但是它不起作用,因为我的新插入的记录是触发器中两个表Test和inserted的一部分。所以插入表中的新记录总是与Test表中的自身连接。触发器将始终回滚事务。
我无法区分新记录和现有记录。因此,如果我排除相同的日期范围,我将能够在表中插入多个完全相同的范围。
主要问题是:
是否可能编写一个触发器,而不向Test表添加附加的标识列,以便我可以使用它来从我的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
重要提示:如果“无法在身份不明的情况下完成”是唯一答案,欢迎您提出,并附上合理的解释。
where
子句的unique
约束实际上可以使其工作。当您插入重叠的日期范围时,会出现错误。 - Robert Koritnik