我们最近进行了更改,以基于以前在存储过程中使用的逻辑创建约束,其中一部分包括使用INSTEAD OF
触发器来集中逻辑。
逻辑通常很简单:
- 存储过程包含针对视图的 INSERT(或 UPDATE)语句,该视图具有 INSTEAD OF INSERT/UPDATE 触发器
- 触发器包含实际逻辑——通常是两条语句,处理将记录插入/更新到主表和一个(或多个)支持表(包括参照完整性)。
问题是在触发器的语句中遇到类似 CHECK 约束的情况。交易被转储,一切都被回滚。我正在考虑必须在有问题的存储过程中复制 CHECK/etc 约束以在触发器执行之前进行验证——是否有其他选择?
可能不是。违反声明性约束将始终引发错误并阻止事务提交违反约束的写入。数据库约束——检查、外键、唯一性等——的要点是它们通过中止违反约束的写入来防止无效数据被记录在数据库中。违反约束会引发错误并回滚事务。
如果您希望事务优雅地失败,您将不得不处理异常或在尝试写入数据之前预先验证数据。在后一种情况下,您将不得不替换存储过程中的验证或在应用程序中实施验证。