【问题标题】:Sqlite: table constraints and triggersSqlite:表约束和触发器
【发布时间】:2015-06-24 12:17:01
【问题描述】:

我知道SQLite中触发器的顺序是不确定的(你不能确定先执行哪个触发器),但是,表约束和触发器之间的关系呢?

我的意思是,假设我在列中有一个 UNIQUE(或 CHECK)约束,并且在该表上有一个 BEFORE 和 AFTER UPDATE 触发器。如果修改了 UNIQUE 列,sqlite 什么时候检查 UNIQUE 约束?在调用 BEFORE 触发器之前,在调用 AFTER 触发器之后,在它们之间,还是以未定义的顺序?

我在 SQLite 文档中没有找到任何关于它的内容。

【问题讨论】:

    标签: sqlite triggers constraints


    【解决方案1】:

    SQLite 建议不要在 BEFORE UPDATE/DELETE 触发器中修改数据,因为这会导致未定义的行为(请参阅文档中的 Cautions on the use of before triggers)。

    SQLite 源代码注释 (src/update.c) 中有一个提示,有助于了解幕后发生的事情:

      /* Fire any BEFORE UPDATE triggers. This happens before constraints are
      ** verified. One could argue that this is wrong.
      */
    

    查看源代码,每当 SQLite 更新表时,它都会执行以下操作:

    • 加载更新使用的表数据。
    • 运行 UPDATE 操作(您需要它来填充 old.field 和 new.field)
    • 然后,它执行 BEFORE UPDATE 触发器。
    • 如果 BEFORE UPDATE 触发器没有删除行数据:
      • 加载触发器未使用的表数据。
      • 然后检查约束(主键、外键、唯一性、on..cascade 等)
      • 然后 SQLite 执行 AFTER UPDATE 触发器。
    • 如果任何 BEFORE UPDATE 触发器删除了行数据:
      • 无需检查约束。
      • 不运行任何 AFTER UPDATE 触发器。

    【讨论】:

      【解决方案2】:

      如果文档没有说明,则订单未定义。

      只要触发器在数据库之外没有副作用,这无关紧要,因为如果约束失败,触发器所做的任何更改都会回滚。

      请注意,SQLite 非常重视向后兼容性,因此实际顺序不太可能改变。

      【讨论】:

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