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

Sql 当存在依赖于这些记录的外键时,如何从表中删除记录?,sql,sql-server,Sql,Sql Server,我有很多表的PersonId列都有外键。我需要从数据库中删除一个人 如果我做一个简单的例子: DELETE FROM Persons WHERE PersonId=111 我得到一个错误: 味精547,第16级,状态0,第1行 DELETE语句与引用约束“FK_CIPerson”冲突。冲突发生在数据库“adb”、表“CI”、列“人员Id”中 我一直“沿着树往下走”,从根上删除依赖项。这通常是有效的,直到我得到一个特定的表,它不会让我删除任何进一步。我认为我必须连接两个表,并删除两个表中包含我的

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

如果我做一个简单的例子:

DELETE FROM Persons WHERE PersonId=111
我得到一个错误:

味精547,第16级,状态0,第1行
DELETE语句与引用约束“FK_CIPerson”冲突。冲突发生在数据库“adb”、表“CI”、列“人员Id”中

我一直“沿着树往下走”,从根上删除依赖项。这通常是有效的,直到我得到一个特定的表,它不会让我删除任何进一步。我认为我必须连接两个表,并删除两个表中包含我的
PersonId
的行

此联接以我希望的方式联接表:

SELECT * 
FROM Table1 
INNER JOIN Table2 ON Table1.anId = Table2.someId 
这将生成一个包含
PersonId
(来自
表2
)的联接表。现在我想删除所有行where
PersonId=111
,所以我还需要一个where子句


提前谢谢

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

至少有3种解决方案:

关于级联删除 (正如Gerardo所回答的那样)如果问题只是外键约束,那么您可以使用此选项,删除此人将完成所有其他操作。但这可能并不总是有效的。正如usr所说,在某些情况下,外键比较复杂,并且有点损坏

删除触发器之前 您可以在person表上定义触发器并在删除之前激活它。在触发器中,可以从其他表中删除依赖行。这与级联删除类似,但您对如何执行删除有更多的控制。。。这可能会解决一些复杂的问题

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

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

如果这是经常发生的情况,您应该将外键设置为删除级联上的
。然后,当您删除一个时,它将“级联”跨其他表删除其余的。但是,每个表只有一条sql语句,否则将删除记录。设置一个存储过程,在其中传入id并为您运行所有语句也可能是另一种选择。可以让两个表相互引用,以便您无法删除任何行。在这种情况下,必须暂时禁用FK。但这是非常罕见的,而且不清楚您是否处于这种情况。听起来表CI的Person_ID有自己的子项,必须先删除这些子项,然后才能继续操作。+1有关解释,谢谢,请参阅票据上的级联删除