11

假设我在一个层次结构中有 3 个表:

TableA -> TableB -> TableC

TableC与 有外键关系TableB,与TableB有外键关系TableA

如果我在 中删除一条记录TableA,它应该通过层次结构级联删除。使用ON DELETE CASCADE会很好。

但是,假设我需要INSTEAD OFTableC. 我的理解是INSTEAD OF触发器不能放在有删除级联的表上。取自 MSDN:

对于 INSTEAD OF 触发器,在具有指定级联操作 ON DELETE 的引用关系的表上不允许使用 DELETE 选项。

如果我必须关闭级联删除TableB->TableC,我需要使用INSTEAD OF触发器来强制执行参照完整性,然后我会遇到同样的问题TableB->TableA。这是一个简单的例子,但想象级联路径要大得多。它似乎很容易在一条长长的级联路径中滚雪球。

那么处理这种情况的最佳实践是什么?

4

2 回答 2

4

假设您必须使用 INSTEAD OF 触发器,并且 AFTER 触发器不是一个选项,最好的方法是 a) 严格控制架构,以便您可以 b) 以常规方式编写 INSTEAD OF 触发器以实现 CASCADE DELETE 和其他您需要的其他操作。

像以前一样创建 FK 约束,但没有任何级联行为。在 FK 名称中,使用一些约定来指示应该发生什么样的级联行为和自定义行为,例如:

  • FK_UC_DC_Table1_Table2 -- 更新级联,删除级联
  • FK_UC_DN_Table1_Table3 -- 更新级联,删除集空

使用任何有意义的东西,但一定要创建 FK,它们是代码生成的有用元数据,您可以使用 FK 名称来记录代码生成器的指令。

然后我会更进一步,将这些表隔离在它们自己的模式中。它们的行为方式与其他表不同,并且在您测试和微调代码生成时,它们一开始会出现更多错误。最好将所有这些隔离起来,并通过一个通用容器轻松识别。

专用模式还将通知修改数据的任何人应用不同的规则和行为。

于 2012-06-03T15:29:34.940 回答
3

标准的最佳实践是在视图上定义 INSTEAD OF 触发器,而不是在上。

如果您必须在 FK 更新/删除上使用触发器,您最好使用 AFTER,因为它将始终执行。

如果要取消级联动作但保留 FK,只需将 FK 动作设置为 NO ACTION。

于 2012-06-04T13:20:39.940 回答