I have a MySQL database. I would like to delete all matches where places.match_no > 26 and matches.chart_id = 106.
DELETE matches
FROM kk_matches AS matches
INNER JOIN places ON places.id = matches.place_id
AND places.match_no > 26
WHERE matches.chart_id = 106
This will cause an error:
#1451 - Cannot delete or update a parent row: a foreign key constraint fails...
What to do?
What to do?
Delete the child table dependent row first and then go for deleting parent table row. What you should have actually done is defining CASCADE option while defining your FOREIGN KEY saying ON DELETE CASCADE.
Another option is to have a BEFORE DELETE trigger and in there do DELETE the child table rows
There is another table in your database which has a foreign key to the kk_matches table. Before you can delete a record in the kk_matches table, you need to delete any records in other tables that point to that record in kk_matches. Otherise you would be "orphaning" those other records.
Foreign Keys exist as a means of avoiding these sort of operations that will cause your data to become irrelevant.
You can't delete a row that has a field referenced by a foreign key constraint. You must delete the referencing row first, then delete the row you want (or drop the constraint, if it wasn't intended).
Check this tutorial for more info:
https://www.w3schools.com/sql/sql_foreignkey.asp
Related
DELETE logins, roles
FROM logins
INNER JOIN roles ON logins.`LOGIN_ID`=roles.`LOGIN_ID`
WHERE roles.`LOGIN_ID`=25774;
Query: DELETE logins, roles FROM logins INNER JOIN roles ON
logins.LOGIN_ID=roles.LOGIN_ID WHERE roles.LOGIN_ID=25774
Error Code: 1451 Cannot delete or update a parent row: a foreign key
constraint fails (foodapp.roles, CONSTRAINT roles_ibfk_1 FOREIGN
KEY (LOGIN_ID) REFERENCES logins (LOGIN_ID))
Execution Time : 0 sec Transfer Time : 0 sec Total Time : 0.038
sec
If you don't have ON CASCADE DELETE constraint setup, you will need to Delete the row from child table first. And, then fire a separate query to delete it from the parent table as well.
DELETE FROM roles
WHERE roles.`LOGIN_ID`=25774;
And, then delete from parent table:
DELETE FROM logins
WHERE logins.`LOGIN_ID`=25774;
From Documentation:
If you use a multiple-table DELETE statement involving InnoDB tables
for which there are foreign key constraints, the MySQL optimizer might
process tables in an order that differs from that of their
parent/child relationship. In this case, the statement fails and rolls
back. Instead, you should delete from a single table and rely on the
ON DELETE capabilities that InnoDB provides to cause the other tables
to be modified accordingly.
If ON CASCADE DELETE has been used in the Foreign Key definition, then all you need to do is delete from the Parent table only. It will automatically delete the corresponding rows from the Child table(s).
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.)
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 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.
I am a beginner in innoDB and not very good in database. I m getting confused about foreign keys. I just want to know is:
If I delete a PK( fk on another table)
is the FK on child table also deleted?
So how about if I delete FK on child table?
Record in parent table also deleted?
Also, if I ADD a new record to parent table
child table also added?
How about i add to child table?
How about if i update data?
Please help me, I am very confused about foreign key reference in innoDB database . Guide me to the easiest way. Thanks.
Assuming that the foreign key constraints are defined, supported by the storage engine and are enabled, (i.e. MySQL variable foreign_key_checks = 1, Oracle foreign key constraints enabled and not deferred, etc.)
Q: If I delete a PK( fk on another table) , is the FK on child table also deleted ?
A: If the DELETE rule is specified as CASCADE, then a delete on the parent table will also perform delete operation on the child table. If the DELETE rule is specified as RESTRICT, and there's rows in the child table that reference the parent key, then the DELETE operation will raise an error.
(EDIT: For the sake of completeness, we note that "SET NULL" is another option for an UPDATE or DELETE rule.)
Q: If I delete a row from the child table with a reference to a row in the parent table, is the row in the parent table also deleted ?
A: No. Deleting rows in the child table will have no affect on row in the parent table.
Q: If I INSERT a new row to parent table, will a row also be added to the child table>
A: No. Rows are not automatically inserted to child tables. It's valid (relational database-wise) to have a parent row that does not have any child rows referencing it.
Q: If I INSERT a row to the child table ?
A: No. An insert to the child table does not automatically insert a row to the parent table. (Any non-null value of the foreign key column being inserted to the child table will be validated; the database will verify that there already exists a row in the parent table with a matching value. If there's not, then the INSERT will fail with an error.)
Q: What if I UPDATE values of the foreign key column in the child table.
A: Same as with an insert, the new value will be validated before the update operation proceeds.
Q: What if I UPDATE the value of the primary key in the parent table?
A: If the UPDATE rule on the foreign key is specified as CASCADE, then the related rows in the child table will also be updated, to preserve the relationship between the rows. If the UPDATE rule is RESTRICT, and there are related rows in the child table, the update operation will raise an error.
Foreign keys are designed for enforcing referential integrity. They basically disallow inserts/updates in the child table when the new non-null values of the foreign key column doesn't reference a row in the parent.
The UPDATE and CASCADE rules defined on the foreign key constraint determine the behavior of UPDATE and DELETE operations on the parent table.
What your'e asking about is cascading the update/deletion to the child element.
The docs : http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
Example :
CONSTRAINT FOREIGN KEY (jobAbbr) REFERENCESffxi_jobType(jobAbbr) ON DELETE CASCADE ON UPDATE CASCADE
the "ON DELETE CASCADE" means that when the key is deleted, all the FK's are deleted aswell, this is very useful for data integrity. It's however not automatic.
Deleting a foreign key will not delete the key it's based upon either way.
DELETE FROM tbl_usergroups,'tbl_group' WHERE (tbl_usergroups.tbl_group_GroupID='tbl_group.GroupID') AND(tbl_usergroups.tbl_group_GroupID=27)
GroupID is a foreign key to tbl_usergroups
if the rows are 1:1 mapping then you could use a view over the two tables and delete joined row from the view.
See this answer Does deleting row from view delete row from base table - MYsql? for more information.
If you set the foreign key constraint to cascade on delete, the row in tbl_usergroups should automatically be deleted.
Failing that, you'd have to delete that entry first, and then delete the row in tbl_group once it is no longer referenced by a foreign key.
ITYM
DELETE FROM `tbl_usergroups` WHERE `tbl_usergroups`.`tbl_group_GroupID`=27
DELETE FROM `tbl_group` WHERE `tbl_group`.`GroupID`=27
GroupIDis a foreign key to tbl_usergroups
Then the order of the DELETEs is important.
I'm deleting selected rows from both table in MYSQL, the two tables have foreign keys.
DELETE d,b
FROM A as b
INNER JOIN B as d on b.bid=d.bid WHERE b.name LIKE '%xxxx%';
MYSQL complains about foreign keys even though I'm trying to delete from both tables:
Error: Cannot delete or update a parent row: a foreign key constraint
fails (`yyy/d`, CONSTRAINT `fk_d_bid` FOREIGN KEY (`bid`) REFERENCES
`b` (`bid`) ON DELETE NO ACTION ON UPDATE NO ACTION)
what's the best solution here to delete from both table?
Change this constraint to use ON DELETE CASCADE -- which means that if a row is deleted, then any "child" rows will be automatically deleted as well.
Of course take good care of using CASCADE -- only use it when necessary. If you're overzealous with it, and accidentally do a well-placed DELETE, it might end up deleting half of your database. :)
See documentation on foreign key constraints.
I think I see what you're trying to do
If you can't change the table structure, then you could use 2 statements, the first with a sub-select
delete from B where bid IN (select bid from A where name like '%xxxx%');
delete from A where name like '%xxxx%';