【问题标题】:Prevent inserting overlapping date ranges using a SQL trigger防止使用 SQL 触发器插入重叠的日期范围
【发布时间】: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

但它不起作用,因为我新插入的记录在触发器内是 Testinserted 表的一部分。因此,插入表中的新记录始终与 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


    【解决方案1】:

    我知道这已经得到解答,但我最近解决了这个问题并提出了一些可行的方法(并且在为每个插入的行进行单例查找时表现良好)。请参阅本文中的示例: http://michaeljswart.com/2011/06/enforcing-business-rules-vs-avoiding-triggers-which-is-better/

    (并且它不使用标识列)

    【讨论】:

      【解决方案2】:

      两个小改动,一切正常。

      首先,将 where 子句添加到您的触发器中以从联接中排除重复记录。那么您就不会将插入的记录与它们自己进行比较:

      select *
        from testdatetrigger t
         join inserted i
         on ((i.ValidTo >= t.ValidFrom) and (i.ValidFrom <= t.ValidTo))
        Where not (i.ValidTo=t.Validto and i.ValidFrom=t.ValidFrom)
      

      除了,这将允许精确的重复范围,因此您必须在两列之间添加唯一约束。实际上,您可能希望对每一列都有一个唯一的约束,因为在同一天开始(或结束)的任何两个范围默认情况下是重叠的。

      【讨论】:

      • 谢谢。 unique 约束加上 where 子句实际上使它起作用。插入重叠的日期范围时会出现错误。
      猜你喜欢
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-11
      • 2017-04-26
      相关资源
      最近更新 更多