级联删除或使用触发器?

时间:2009-09-21 21:35:31

标签: sql sql-server tsql sql-server-2008

我正在完成我接管的项目,在数据库方面,我注意到以前的程序员编写了一堆触发器来删除子记录。问题是,这些记录已与我正在删除的父记录具有外键关系。删除触发器只不过是子记录的简单删除语句。

编写触发器以删除子记录是否有好处,或者我可以将其更改为在删除时级联并且没问题吗?

我正在使用MSSQL 2008。

4 个答案:

答案 0 :(得分:16)

MSSQL Server中的

CASCADE DELETE 只能级联到单个表。如果有两个表与维表的外键关系,则只能将删除级联到其中一个表。 (这是为了防止删除级联多个路径并产生冲突,就像C ++允许多重继承但C#只允许单继承一样)

如果是这种情况,您将被迫使用触发器或专门处理代码中的案例。

出于这个原因,我看到很多人选择在所有情况下使用触发器。即使只有一张外国桌子。这确保了一致性,因此人们知道维护数据库时要查找的内容。

如果可以将删除级联到多个表,我会说这将是最优选的选项。然而,这种限制使水泛滥,我现在更倾向于拥有所有这些行为的触发器。使用触发器进行级联删除和更新的开销在编码方面只是次要的,但允许标准实践真正通用。

修改

您可能希望将“已接受的答案”移至其他人,我已经解决了上述问题。

你可以有多个事实表具有ON DELETE CASCADE外键重键对一个标志尺寸表。

你不能做的是有一个事实表对多个维度表有ON DELETE CASCADE外键约束。

所以例如......
- 尺寸表[人物](id INT IDENTITY,)
- 尺寸表[考试](id INT IDENTITY,)
- 面部表[Exam_Score](person_id INT,exam_id INT,得分INT)

如果删除了人员或考试,您还希望删除相关的Exam_Score记录。

这在MS SQL Server中使用ON DELETE CASCADE是不可能的,因此需要触发器。

(向Mehrdad道歉,他试图向我解释这一点,但我完全错过了他的观点。)

答案 1 :(得分:10)

远离不必要的触发器。

如果您需要这样做,请使用ON DELETE CASCADE

答案 2 :(得分:1)

我会在删除时使用cascade,但这只是在您删除父级时肯定要删除子级的时候。

如果您有任何条件逻辑(我只删除了在星期日删除的孩子),那么使用触发器。

我只想在开发系统上将其更改为cascade on delete,然后运行我的单元测试并确保没有任何损坏。

答案 3 :(得分:1)

我几乎同意这里的Dems,除非我尽可能使用ON DELETE CASCADE(以及ON UPDATE CASCADE)参考动作,并且只在必要时使用触发器。我还考虑从表中撤销权限并强制使用'helper'存储过程进行删除和更新。

称我为乐观主义者,但我相信a)我的代码将继续移植到未来的MS SQL Server版本中,并且b)SQL Server团队将很快有一天能够解决“一个级联路径”限制,我将用级联参考动作替换触发器:)