【发布时间】:2010-10-26 11:28:12
【问题描述】:
我有一张简化后的表格,如下所示:
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 表中的自身连接。触发器将始终还原事务。
我无法区分新记录和现有记录。因此,如果我排除相同的日期范围,我将能够在表中插入多个完全相同的范围。
主要问题是
是否可以编写一个按预期工作的触发器,而无需在我的测试表中添加一个额外的标识列,我可以用它来从我的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
重要提示:如果没有身份就不可能是唯一的答案,我欢迎您提出并合理解释原因。
【问题讨论】:
标签: sql tsql sql-server-2008 triggers date-range