当存在依赖于这些记录的外键时,如何从表中删除记录?

时间:2014-06-03 16:21:23

标签: sql sql-server

我有很多外键键入PersonId列的表。我需要从数据库中删除一个人。

如果我做的很简单:

DELETE FROM Persons WHERE PersonId=111

我收到错误:

  

Msg 547,Level 16,State 0,Line 1
  DELETE语句与REFERENCE约束" FK_CIPerson"冲突。冲突发生在数据库" adb",table" CI",column' Person_Id'。

我继续走下树#34;依赖和从根删除。这通常是有效的,直到我到达某个表格,它不允许我进一步删除。我相信我必须加入2个表并删除其中包含PersonId的BOTH表中的行。

此连接以我希望它们加入的方式连接表:

SELECT * 
FROM Table1 
INNER JOIN Table2 ON Table1.anId = Table2.someId 

这会导致联接表格中包含PersonId(来自Table2)。我现在想要删除PersonId=111所有的行,所以我也需要一个where子句。

提前致谢!

2 个答案:

答案 0 :(得分:1)

根据定义,SQL DELETE语句仅影响一个表。如果需要级联删除,可以使用@paqogomez建议简化:只需在外键声明上指定ON DELETE CASCADE选项。

答案 1 :(得分:1)

至少有3种解决方案:

ON CASCADE DELETE

(正如Gerardo所回答的)如果问题只是外键约束,那么你可以使用它并删除该人将完成所有其余工作。但这可能并不总是奏效。正如usr所说,在某些情况下,外键很复杂并且有点损坏。

在删除TRIGGER之前

您可以在人员表上定义触发器并在BEFORE DELETE之前激活它。在触发器中,您可以处理从其他表中删除相关行的问题。这类似于ON CASCADE DELETE,但您可以更好地控制如何执行删除...这可以解决其中一些复杂问题。

存储过程

您可以使用person_id参数定义存储过程。代码类似于触发器。但是在存储过程中,您有时可以执行一些额外操作,例如停用外键(但不确定SQL Server)。

DELETION SCRIPT

这是最强大的,因为你可以混合使用DDL和SQL并做各种各样的事情。但是脚本通常必须手动运行,这在您的情况下可能是不可接受的。