我有以下情况。一个主表和许多其他表通过外键链接在一起。现在,当我想删除主表中的一行时,会发生 ConstraintsViolation,这是有意且好的。
现在我希望能够在触发删除行事件之前检查 ConstraintsViolation 是否会发生。
这可能吗?
我有以下情况。一个主表和许多其他表通过外键链接在一起。现在,当我想删除主表中的一行时,会发生 ConstraintsViolation,这是有意且好的。
现在我希望能够在触发删除行事件之前检查 ConstraintsViolation 是否会发生。
这可能吗?
这是一个表面上看起来很好,但有含义的问题。
首先,您需要确保在阅读了这些关系的状态后,没有人可以更改它们,因此显然您需要使用事务并锁定有问题的行。
然后,您需要一种方法来确定要检查的关系,正如我在此处的评论中看到的那样,您的问题是如果有人稍后添加新关系会发生什么。所以你需要查询模式,或者从模式中自动生成这段代码,这样检测机制只需要在每次更改模式时运行。
现在,在经历了这次磨难之后,你得到的例外真的看起来那么昂贵吗?
If Exists ( Select * From OtherTable
Where OtherTableFKColumn = MainTablePrimaryKey)
Begin
Rollback Transaction
RaisError('Violating FK Constraint in Table [OtherTable]', 16, 1)
End
除了检查COUNT(*)
每个相关表的之外?我不这么认为。
一个丑陋的尝试是在事务中尝试删除,然后在成功时强制回滚。但这对我来说太脏了。
我认为尝试这样的事情不是一个好主意,因为这意味着每个外键都必须检查两次:事先由您检查一次,然后在您执行 SQL 时由服务器再次检查。性能影响可能很严重。
但是,如果您下定决心这样做,最通用的方法是使用数据库的数据字典。我不熟悉 SQL Server 数据字典,但其他关系数据库将其所有元数据存储在您可以查询的数据库表中。您可以找到引用您的表的所有外键并动态构建查找相关行的查询。