INSTEAD OF触发器和CASCADE路径

Bre*_*tin 10 sql sql-server triggers referential-integrity cascade

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

TableA -> TableB -> TableC
Run Code Online (Sandbox Code Playgroud)

TableC与外键有关系TableB,并且与TableB外键有关系TableA.

如果我删除了一个记录TableA,它应该通过层次结构向下级联删除.使用ON DELETE CASCADE会很好.

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

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

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

那么处理这种情况的最佳做法是什么?

Pet*_*hia 4

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

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

  • FK_UC_DC_Table1_Table2 -- 更新级联、删除级联
  • FK_UC_DN_Table1_Table3 -- 更新级联,删除设置为空

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

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

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