简体   繁体   中英

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 )

First thing: I do not have any such table with this name "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 .

Those rows are related to rows in the user_surveys table.

Likely, there's a foreign key constraint defined on table user_surveys that references rows in surveys you are attempting to delete.

(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 . (Likely, its a column named survey_id , but we're just guessing without looking at the definitions of the foreign key constraints.)

To find the rows in user_surveys_archive that are preventing the DELETE from happening...

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 . The attempt to delete rows from surveys identifies rows in user_surveys that should automatically be removed.

The attempt to automatically remove the rows from user_surveys is what's violating the foreign key constraint defined in user_surveys_archive . And that foreign key is not defined with ON DELETE CASCADE .

(The other possibility is that there's a trigger defined that's doing some DML operations, but that would be odd.)


Once you identify the rows, you need to decide what changes to make to allow you to remove rows from 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 . If the user_access_level_id column in user_surveys_archive allows for NULL values, you can do an update.

Replace SELECT a.* FROM with UPDATE , and add SET a.user_access_level_id = NULL on a line above the WHERE clause...

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.)

The survey_id of 77 must be referenced in a table possibly named user_surveys_archive . The error is saying the name of the foreign key restraint which is the 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.

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 . 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.

Edit 2 spencer7593's answer lays out how to run some of the queries mentioned in my answer.

You should allow the foreign key to be NULL and then choose 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.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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