简体   繁体   English

SQL:无法删除或更新父行:外键约束失败

[英]SQL: Cannot delete or update parent row: a foreign key constraint fails

Whenever I try to delete a survey from table "survey" like this: 每当我尝试从表“调查”中删除调查时,如下所示:

DELETE FROM surveys WHERE survey_id = 77

It prompts me an error stated below: 它提示我一个错误如下:

#1451 - Cannot delete or update a parent row: a foreign key constraint fails ('user_surveys_archive', CONSTRAINT 'user_surveys_archive_ibfk_6' FOREIGN KEY ('user_access_level_id') REFERENCES 'user_surveys' ('user_access_level_id') ON DELETE NO ACTION ) #1451 - 无法删除或更新父行:外键约束失败('user_surveys_archive',CONSTRAINT'user_surveys_archive_ibfk_6'FOREIGN KEY('user_access_level_id')REFERENCES'user_surveys'('user_access_level_id')ON DELETE NO ACTION)

First thing: I do not have any such table with this name "user_surveys_archive_ibfk_6" 第一件事:我没有任何这样的名称为“user_surveys_archive_ibfk_6”的表

2nd thing: There is no record of this survey in other tables. 第二件事:其他表格中没有此调查的记录。

Any idea on how can I delete this record of fix this issue? 有关如何删除此修复此问题的记录的任何想法?

Edit 编辑

This is the line I found when I export the table Constraints for table surveys 这是我在导出表调查的表约束时找到的行

ALTER TABLE `surveys`
ADD CONSTRAINT `surveys_ibfk_1` FOREIGN KEY (`survey_type_id`) REFERENCES `survey_types` (`survey_type_id`) ON DELETE CASCADE ON UPDATE NO ACTION;`

You will need to first remove or update some rows in table user_surveys_archive . 您需要先删除或更新表user_surveys_archive某些行。

Those rows are related to rows in the user_surveys table. 这些行与user_surveys表中的行相关。

Likely, there's a foreign key constraint defined on table user_surveys that references rows in surveys you are attempting to delete. 可能,表user_surveys上定义了一个外键约束,它引用了您尝试删除的surveys行。

(You'd need to check the foreign key definition, quickest way to get that is a (您需要检查外键定义,最快的方法是获取它

SHOW CREATE TABLE user_surveys 

And look for REFERENCES surveys . 并寻找REFERENCES surveys (Likely, its a column named survey_id , but we're just guessing without looking at the definitions of the foreign key constraints.) (可能,它的一个名为survey_id的列,但我们只是猜测而不考虑外键约束的定义。)

To find the rows in user_surveys_archive that are preventing the DELETE from happening... 要在user_surveys_archive中查找阻止DELETE发生的行...

SELECT a.*
  FROM user_surveys_archvive a
  JOIN user_surveys u
    ON u.user_access_level_id = a.user_access_level_id  
  JOIN surveys s
    ON s.survey_id = u.survey_id    -- change this to whatever the FK is
 WHERE s.survey_id = 77

It's likely that the foreign key constraint from user_surveys to surveys is defined with ON DELETE CASCADE . user_surveyssurveys的外键约束可能是使用ON DELETE CASCADE定义的。 The attempt to delete rows from surveys identifies rows in user_surveys that should automatically be removed. surveys删除行的尝试标识了user_surveys中应自动删除的行。

The attempt to automatically remove the rows from user_surveys is what's violating the foreign key constraint defined in user_surveys_archive . 尝试从user_surveys自动删除行是违反user_surveys_archive定义的外键约束的user_surveys_archive And that foreign key is not defined with ON DELETE CASCADE . 并且该外键使用ON DELETE CASCADE定义。

(The other possibility is that there's a trigger defined that's doing some DML operations, but that would be odd.) (另一种可能性是定义了一个触发器,它正在做一些DML操作,但这很奇怪。)


Once you identify the rows, you need to decide what changes to make to allow you to remove rows from surveys . 识别行后,您需要确定要进行哪些更改以允许从surveys删除行。

You can either DELETE the rows, or UPDATE them. 您可以删除行,也可以更新它们。

To delete the rows from user_surveys_archive , modify the query above and replace SELECT with DELETE . 要从user_surveys_archive删除行,请修改上面的查询并将SELECT替换为DELETE If the user_access_level_id column in user_surveys_archive allows for NULL values, you can do an update. 如果user_access_level_iduser_surveys_archive允许NULL值,你可以做一个更新。

Replace SELECT a.* FROM with UPDATE , and add SET a.user_access_level_id = NULL on a line above the WHERE clause... UPDATE替换SELECT a.* FROM ,并在WHERE子句上方的一行上添加SET a.user_access_level_id = NULL ...

UPDATE user_surveys_archvive a
  JOIN user_surveys u
    ON u.user_access_level_id = a.user_access_level_id  
  JOIN surveys s
    ON s.survey_id = u.survey_id    -- change this to whatever the FK is
   SET a.user_access_level_id = NULL
 WHERE s.survey_id = 77

(It seems strange to me that name of the foreign key column is user_access_level_id . But its just a column name, it could be named anything... seems odd to me because of the conventions and patterns that we follow in naming foreign key columns.) (对我来说,外键列的名称是user_access_level_id似乎很奇怪。但它只是一个列名,它可以命名为任何东西......对我来说似乎很奇怪,因为我们在命名外键列时遵循了约定和模式。 )

The survey_id of 77 must be referenced in a table possibly named user_surveys_archive . 必须在名为user_surveys_archive的表中引用survey_id of 77。 The error is saying the name of the foreign key restraint which is the user_surveys_archive_ibfk_6 . 错误是说外键约束的名称是user_surveys_archive_ibfk_6 If you need to delete survey_id = 77 you will have to delete any child records or other records that reference it as a foreign key. 如果您需要删除survey_id = 77 ,则必须删除任何子记录或将其作为外键引用的其他记录。

Edit After posting my answer I saw the comments above. 编辑发布我的回答后,我看到了上面的评论。 atif the foreign key in the user_surveys_archive table may be named differently but still equal the value of 77 that you are trying to delete, and/or be referencing the survey_id . atif user_surveys_archive表中的外键可能名称不同,但仍等于您尝试删除的值77,和/或引用survey_id If that is not the case then there are some other problems within the database. 如果不是这种情况,那么数据库中还存在一些其他问题。 You could try and look at the code for the FK to see how it was made and what fields it is referencing, or run a query to see if there are any records in the user_surveys_archive where the user_access_level_id is = 77. 您可以尝试查看FK的代码以查看它是如何创建的以及它引用的字段,或运行查询以查看user_surveys_archiveuser_access_level_id是否为77的任何记录。

Edit 2 spencer7593's answer lays out how to run some of the queries mentioned in my answer. 编辑2 spencer7593的答案列出了如何运行我的答案中提到的一些查询。

You should allow the foreign key to be NULL and then choose ON DELETE SET NULL . 您应该允许外键为NULL ,然后选择ON DELETE SET NULL

Personally I would recommend using both "ON UPDATE CASCADE" as well as "ON DELETE SET NULL" to avoid unnecessary complications, however your setup may dictate a different approach. 我个人建议使用“ON UPDATE CASCADE”以及“ON DELETE SET NULL”以避免不必要的复杂情况,但是您的设置可能会指示不同的方法。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM