【问题标题】:Using Triggers To Enforce Constraints使用触发器强制约束
【发布时间】:2009-01-09 15:00:58
【问题描述】:

我正在尝试以我认为约束无法实现的方式对表强制执行完整性...

CREATE TABLE myData
(
   id             INTEGER IDENTITY(1,1) NOT NULL,
   fk_item_id     INTEGER               NOT NULL,
   valid_from     DATETIME              NOT NULL,
   invlaid_from   DATETIME              NOT NULL
)

我要应用的约束是,对于相同的“fk_item_id”,不应有任何具有重叠日期的条目。

注意:

invalid_from 是有效期之后的瞬间。
意思就是后面两个时期都可以……

  • '2008 Jan 01 00:00' -> '2008 Feb 01 00:00'(整个一月)
  • '2008 Feb 01 00:00' -> '2008 Mar 01 00:00'(整个 2 月)

我可以在触发器中检查该规则。但是,当触发器确实发现非法插入/更新时,防止“非法”插入/更新发生的最佳方法是什么?

(如果inserted包含两条有效记录和两条无效记录,我可以只停止这两条无效记录吗?)

干杯,
德姆斯。

编辑:

在上述情况下,使用函数的约束效果很好。但我从来没有弄清楚为什么 RAISERROR 在触发器版本中不起作用。

我认为这是因为触发器是 AFTER 触发器,我需要一个 BEFORE 触发器,但这似乎不是一个选项...

【问题讨论】:

    标签: sql sql-server sql-server-2005 triggers constraints


    【解决方案1】:

    您不能直接从插入的表中删除(更新逻辑表会引发错误),但您可以连接回源表,如下所示

    create table triggertest (id int null, val varchar(20))
    Go
    create trigger after  on [dbo].triggertest
    for Update  
    as
    Begin
    
        delete tt from triggertest tt inner join 
        inserted i on tt.id = i.id 
        where i.id = 9
    
    End
    GO
    insert into triggertest values (1,'x')
    insert into triggertest values (2,'y')
    Update triggertest set id = 9 where id = 2
    select * from triggertest
    1, x
    

    另外,你不必走触发路线,你也可以将检查约束绑定到函数的返回值

    Alter table myData WITH NOCHECK add 
    Constraint  CHK_VALID CHECK (dbo.fx_CheckValid(id, valid_from , invalid_from) = 1 );
    

    【讨论】:

    • +1 for the Constraint -> UDF,我已经完成了这个并且喜欢它的工作原理。
    【解决方案2】:

    不要从插入的表中删除记录...这是静默失败。通往地狱的路是在 Partial Commits 中铺就的。

    您需要RAISERROR,这基本上是constraint 会做的事情。

    【讨论】:

      【解决方案3】:

      您的触发器可以将“非法”记录的valid_from 和/或invlaid_from DATETIMEs 修改为特殊值。随后的清理步骤可以识别“非法”记录。

      【讨论】:

        【解决方案4】:

        引发错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-26
          • 1970-01-01
          • 1970-01-01
          • 2015-04-25
          相关资源
          最近更新 更多