我有一个表,其中包括名为StartTime和EndTime的两个字段。两者都是TIME字段。
我想添加一个约束,以防止插入任何与先前存在的时间范围重叠的记录。例如。如果已经存在StartTime = 5:00,EndTime = 10:00的记录,我希望插入时StartTime = 6:00,EndTime = 9:00因重叠而失败。
有没有办法实现这一点,有或没有触发器?
答案 0 :(得分:5)
下面的触发器应该可以工作 - 也可以使用检查约束来执行此操作,但this post中显示的逻辑会伤害我的头脑。
CREATE TRIGGER [dbo].[DateRangeTrigger]
ON [dbo].[TargetTable]
FOR INSERT, UPDATE
AS
BEGIN
IF EXISTS (SELECT t.starttime, t.endtime FROM TargetTable t
Join inserted i
On (i.starttime > t.starttime AND i.starttime < t.endtime AND i.UniqueId <> t.UniqueId)
OR (i.endtime < t.endtime AND i.endtime > t.starttime AND i.UniqueId <> t.UniqueId)
OR (i.starttime < t.starttime AND i.endtime > t.endtime AND i.UniqueId <> t.UniqueId)
)
BEGIN
RAISERROR ('Inserted date was within invalid range', 16, 1)
IF (@@TRANCOUNT>0)
ROLLBACK
END
END
答案 1 :(得分:4)
我没有尝试过,但我想这样的事情会起作用:
create trigger preventOverlaps
on infotable
FOR Insert, Update
As
DECLARE @Count int;
select @Count = count(*) from infotable where
(inserted.startdate > startDate && inserted.startdate < endDate) ||
(inserted.endDate < endDate && inserted.endDate > startDate)
if(@Count > 0)
begin
rollback transaction;
end
答案 2 :(得分:2)
此触发器也适用于一个时间跨度完全包含另一个的情况。例如,如果现有记录为6:00 - 9:00,并且您尝试在5:00 - 10:00插入一个记录。
(根据David Hall的回答)
CREATE TRIGGER DateRangeOverlapTrigger
ON TargetTable
FOR INSERT, UPDATE
AS
BEGIN
IF EXISTS
(SELECT t.UniqueId
FROM TargetTable t
JOIN inserted i ON i.starttime < t.endtime
AND i.endtime > t.starttime
AND i.UniqueId <> t.UniqueId)
BEGIN
RAISERROR ('Invalid due to time overlap', 16, 1)
IF (@@TRANCOUNT > 0)
ROLLBACK
END
END