Cannot delete a row because of foreign key constraint - mysql

I have two tables. user and comment. I wanted the users to be able to vote up comments so I made another table called user_vote_comment. I let the id column on the user table and the id column on the comment table be a composite primary key on the user_vote_comment table.
This is the structure of the user_vote_comment table:
CREATE TABLE IF NOT EXISTS `user_vote_comment` (
`user_id` INT(11) UNSIGNED NOT NULL,
`comment_id` INT(11) UNSIGNED NOT NULL,
PRIMARY KEY (`user_id`, `comment_id`),
INDEX `fk_user_vote_comment_comment1_idx` (`comment_id` ASC),
CONSTRAINT `fk_user_vote_comment_user1`
FOREIGN KEY (`user_id`)
REFERENCES `user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_user_vote_comment_comment1`
FOREIGN KEY (`comment_id`)
REFERENCES `comment` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
Now I added some rows to the user_vote_comment but then I wanted to delete some votes because I wanted the users to have that option, to unvote. But then I get this error message:
Error 1451: Cannot delete or update a parent row: a foreign key constraint fails (`user_vote_comment`, CONSTRAINT `fk_user_vote_comment_comment1` FOREIGN KEY (`comment_id`) REFERENCES `comment` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
I thought the user and comment table were the parent tables here? Since it makes sense that it is a constraint if I was to delete a user or a comment then I should get an error because some rows in the user_vote_comment are dependent on that info, but not the other way around?
I don't understand why I can't delete the rows in the user_vote_comment, I feel that I am too much restricted if I can't even remove rows from it.
What should I do?

I don't think anything is wrong with your SQL. May be you've missed mentioning something else in the above problem which is causing the issue?
I did a quick test with SQLFiddle (http://www.sqlfiddle.com/#!9/c726aa/1/0) and I'm able to delete from USER_VOTE_COMMENT table just fine.

You can set ON DELETE CASCADE instead of ON DELETE NO ACTION

Related

Remove primary key(s) - Foreign key constraint is incorrectly formed

I cannot seem to be able to delete primary keys in a table.
All references (FKs) have been removed but it still doesn't let me delete it.
What I'm trying to do is: delete old primary keys to add a new one - but keep the old columns and data (just remove the PK attribute).
What is wrong ?
Table:
CREATE TABLE `employee` (
`User` int(10) unsigned NOT NULL,
`Company` int(10) unsigned NOT NULL,
--unrelated boolean fields
PRIMARY KEY (`User`,`Company`),
KEY `FK_Employee_Company_idx` (`Company`),
CONSTRAINT `FK_Employee_Company` FOREIGN KEY (`Company`) REFERENCES `company` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_Employee_User` FOREIGN KEY (`User`) REFERENCES `user` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Trying to delete:
alter table Employee
drop primary key;
Issue:
Error 1025: Error on rename of '.\DB_NAME#sql-3640_4' to '.\DB_NAME\employee' (errno: 150 "Foreign key constraint is incorrectly formed") SQL Statement: ALTER TABLE DB_NAME.employee DROP PRIMARY KEY
Nothing references this table anymore. I also checked via statements which select from information_schema.key_column_usage but yields no results.
Wasted the last hours on Google but can't seem to figure it out.
And if that would work, adding a new column:
alter table Employee
add column ID int unsigned not null auto_increment primary key;
The index is still needed for the existing FK constraints.
Adding the following index (first) should satisfy that requirement:
CREATE INDEX xxx ON employee (User, Company);
Test case

Mysql: Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails

I have this table:
CREATE TABLE comments(
comment_id int(11) NOT NULL auto_increment,
user_id int(11) NOT NULL,
product_id int(11) NOT NULL,
comment_text varchar(1000) COLLATE utf8_czech_ci NOT NULL,
uploaded datetime NOT NULL,
primary key(comment_id),
constraint fk_user_comments foreign key(user_id) references user(user_id) ON UPDATE CASCADE ON DELETE CASCADE,
constraint fk_product_comments foreign key(product_id) references product(product_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
and I'm trying to insert data into this table.
INSERT INTO comments(user_id,product_id,comment_text,uploaded) VALUES(1,'brbr',1,Now());
But for some reason I keep getting this error:
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`project`.`comments`, CONSTRAINT `fk_product_comments` FOREIGN KEY (`product_id`) REFERENCES `product` (`product_id`) ON DELETE CASCADE ON UPDATE CASCADE)
User with id 1 exists and product with id 1 exists so now i have no idea whats causing the problem.
You've got your column list's order messed up.
You're attempting to insert a row with a product_id of 'brbr' (which MySQL treats as 0) and a comment text of 1 (which MySQL converts as to '1').
Reordering the the column list to match the values (or vise-versa) should solve it:
INSERT INTO comments
(user_id, product_id, comment_text, uploaded)
VALUES (1, 1, 'brbr', NOW());
-- Here ---^
This because you are not adding value according to your column sequence.
This is correct query.
INSERT INTO comments(user_id,product_id,comment_text,uploaded) VALUES(1,1,'brbr',Now())
I met the same problem today as I was dealing with Schema that wasn't designed by me. I added tables and relationships (FK) and things went KaBoom!
Upon investigation, I found the other buddy was using MyIsam Engine for that table and I was using InnoDB.
Changing the table from MyIsam to InnoDB ssolved the Issue!

ERROR 1452: Cannot add or update a child row: a foreign key constraint fails

I have created two tables in MySQL 5.6.11 as shown below by means of MySQL Workbench 5.2.47.
The country table:
delimiter $$
CREATE TABLE `country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INC
REMENT=2 DEFAULT CHARSET=utf8$$
The state_table:
delimiter $$
CREATE TABLE `state_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`state_name` varchar(45) DEFAULT NULL,
`country_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `country_fk` FOREIGN KEY (`id`) REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT=''$$
There is one row in the country table with the id 1. It allows only one (child) row to be inserted into its child table state_table. If more rows are attempted, then the following error occurs.
ERROR 1452: Cannot add or update a child row: a foreign key constraint
fails (social_networking.state_table, CONSTRAINT country_fk
FOREIGN KEY (id) REFERENCES country (id) ON DELETE CASCADE ON
UPDATE CASCADE)
SQL Statement:
INSERT INTO `social_networking`.`state_table` (`id`, `state_name`, `country_id`) VALUES ('2', 'xxx', '1')
Actually, I'm trying to map these tables using an ORM (JPA) where I always see only OneToOne relationship.
What am I missing?
Well, I find the answer, the solution, my english is not very well but I think can explain you. I get this error after try to create a trigger, My database was created in phpmyadmin, and this error was make me crazy, the problem was that I before create the trigger, I load a lot of data in my tables, and in my child table was some data that have no match in my parent table, ej: my child table "chat" have a "id_jugador=1" and in my parent table there wasn't that "id_jugador", that was my mistake, I hope help you, Argentina Rulz ;)
I think you have a typo in your foreign key constraint, country_id should probaby be the foreign key to country. When id is the foreign key, you can only insert one row since it just happens to get id=1 which is the same id as the row in country;
CONSTRAINT `country_fk` FOREIGN KEY (`id`)
REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
should probably be
CONSTRAINT `country_fk` FOREIGN KEY (`country_id`)
REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
An SQLfiddle to test with.
I had the same problem and it was not wrong relationships name.
I had problem with different records, ie, tried registering a record that did not exist in another table so generated this error.
Check if the record exists in another table to insert their correct relationship, otherwise, this error appears.
Hope this help you.
example:
table1(
id1 INT PRIMARY KEY,
name1 VARCHAR(50)
)
table2(
id2,<--- want to add FOREIGN KEY to this field
name2 VARCHAR(50)
)
Before adding constraint foreign key you must have the right value between id1 and id2, so you should update that id field with the value that map each other.
Possible Solution
if you have live data, then check all column values.
i.e. if you have 'x'->table as primary one having 'a'->column and 'y'->table as secondary with 'b'->column, then all values in 'b'->column must exist in 'a'->column if any value that exists in 'b'->column and not exist in 'a'->column then it will give as such error..
Hope this help.. for newbie..

Error (150) Generated By An SQL Script?

I am trying to create a table on MySQL using an SQL script and the MySQL database keeps on giving me error 150. I've tried the following code in both Navicat and MySQL Workbench and both give an 150 error.
It appears that this is a foreign key problem but i cant actually see what the problem with my code is and was wondering if more expereinced DB users would have any inkling to the problem?
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE `network_invites` (
`invite_ID` int(11) NOT NULL AUTO_INCREMENT,
`invite_From` int(11) NOT NULL,
`invite_Network` int(11) NOT NULL,
`invite_NetCreator` int(11) NOT NULL,
`invite_Message` varchar(256) NOT NULL,
`invite_Date` date DEFAULT NULL,
PRIMARY KEY (`invite_ID`),
KEY `invite_From` (`invite_From`),
KEY `invite_Network` (`invite_Network`),
KEY `invite_NetCreator` (`invite_NetCreator`),
CONSTRAINT `network_invites_ibfk_1` FOREIGN KEY (`invite_From`) REFERENCES `users` (`user_ID`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `network_invites_ibfk_2` FOREIGN KEY (`invite_Network`) REFERENCES `networks` (`network_ID`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `network_invites_ibfk_3` FOREIGN KEY (`invite_NetCreator`) REFERENCES `networks` (`network_Creator`) ON DELETE CASCADE ON UPDATE CASCADE
)ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
I cant see what the FK problem is, those fields do exist on the DB and they are of the same datatype.
Thanks for any help.
I think the workaround is :
create the table without constraints
add constraints using ALTER TABLE
again , this is a workaround , and would love to hear from people#mysql or someone more experienced
Make sure the 2 Table Types are both InnoDB. Also make sure your Primary and Foreign keys are all Unsigned.
All these settings can be changed in NaviCat using the "Design Table" option.
I've come across this problem many times, and this does the trick 99% of the time.
You need to have indexes on users.user_ID, networks.network_ID and networks.network_Creator and the types of the columns should be exactly the same as in the network_invites table.
The problem is a typo:
CONSTRAINT `network_invites_ibfk_2`
FOREIGN KEY (`invite_Network`)
REFERENCES `networks` (`network_ID`) ---<--- either here
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `network_invites_ibfk_3`
FOREIGN KEY (`invite_NetCreator`)
REFERENCES `networks` (`network_Creator`) ---<--- or here (more probable)
ON DELETE CASCADE ON UPDATE CASCADE
Your networks table Primary Key is probably network_ID and not network_Creator.

Cannot delete or update a parent row: a foreign key constraint fails

When doing:
DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1
It errors:
#1451 - Cannot delete or update a parent row: a foreign key constraint fails
(paymesomething.advertisers, CONSTRAINT advertisers_ibfk_1 FOREIGN KEY
(advertiser_id) REFERENCES jobs (advertiser_id))
Here are my tables:
CREATE TABLE IF NOT EXISTS `advertisers` (
`advertiser_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`password` char(32) NOT NULL,
`email` varchar(128) NOT NULL,
`address` varchar(255) NOT NULL,
`phone` varchar(255) NOT NULL,
`fax` varchar(255) NOT NULL,
`session_token` char(30) NOT NULL,
PRIMARY KEY (`advertiser_id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
INSERT INTO `advertisers` (`advertiser_id`, `name`, `password`, `email`, `address`, `phone`, `fax`, `session_token`) VALUES
(1, 'TEST COMPANY', '', '', '', '', '', '');
CREATE TABLE IF NOT EXISTS `jobs` (
`job_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`advertiser_id` int(11) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`shortdesc` varchar(255) NOT NULL,
`longdesc` text NOT NULL,
`address` varchar(255) NOT NULL,
`time_added` int(11) NOT NULL,
`active` tinyint(1) NOT NULL,
`moderated` tinyint(1) NOT NULL,
PRIMARY KEY (`job_id`),
KEY `advertiser_id` (`advertiser_id`,`active`,`moderated`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
INSERT INTO `jobs` (`job_id`, `advertiser_id`, `name`, `shortdesc`, `longdesc`, `address`, `active`, `moderated`) VALUES
(1, 1, 'TEST', 'TESTTEST', 'TESTTESTES', '', 0, 0);
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`);
The simple way would be to disable the foreign key check; make the changes then re-enable foreign key check.
SET FOREIGN_KEY_CHECKS=0; -- to disable them
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them
As is, you must delete the row out of the advertisers table before you can delete the row in the jobs table that it references. This:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`)
REFERENCES `jobs` (`advertiser_id`);
...is actually the opposite to what it should be. As it is, it means that you'd have to have a record in the jobs table before the advertisers. So you need to use:
ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`)
REFERENCES `advertisers` (`advertiser_id`);
Once you correct the foreign key relationship, your delete statement will work.
Under your current (possibly flawed) design, you must delete the row out of the advertisers table before you can delete the row in the jobs table that it references.
Alternatively, you could set up your foreign key such that a delete in the parent table causes rows in child tables to be deleted automatically. This is called a cascading delete. It looks something like this:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`)
ON DELETE CASCADE;
Having said that, as others have already pointed out, your foreign key feels like it should go the other way around since the advertisers table really contains the primary key and the jobs table contains the foreign key. I would rewrite it like this:
ALTER TABLE `jobs`
ADD FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`);
And the cascading delete won't be necessary.
Disable the foreign key check and make the changes then re-enable foreign key check.
SET FOREIGN_KEY_CHECKS=0; -- to disable them
DELETE FROM `jobs` WHERE `job_id` = 1 LIMIT 1
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them
If you want to drop a table you should execute the following query in a single step
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE table_name;
I tried the solution mentioned by #Alino Manzi but it didn't work for me on the WordPress related tables using wpdb.
then I modified the code as below and it worked
SET FOREIGN_KEY_CHECKS=OFF; //disabling foreign key
//run the queries which are giving foreign key errors
SET FOREIGN_KEY_CHECKS=ON; // enabling foreign key
I think that your foreign key is backwards. Try:
ALTER TABLE 'jobs'
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`)
If there are more than one job having the same advertiser_id, then your foreign key should be:
ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`)
REFERENCES `advertisers` (`advertiser_id`);
Otherwise (if its the other way round in your case), if you want the rows in advertiser to be automatically deleted if the row in job is deleted add the 'ON DELETE CASCADE' option to the end of your foreign key:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`)
REFERENCES `jobs` (`advertiser_id`)
ON DELETE CASCADE;
Check out Foreign Key constraints
You need to delete it by order
There are dependency in the tables
When you create database or create tables
You should add that line at top script create database or table
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
Now you want to delete records from table? then you write as
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1
Good luck!
How about this alternative I've been using: allow the foreign key to be NULL and then choose ON DELETE SET NULL.
Personally I prefer using both "ON UPDATE CASCADE" as well as "ON DELETE SET NULL" to avoid unnecessary complications, but on your set up you may want a different approach. Also, NULL'ing foreign key values may latter lead complications as you won't know what exactly happened there. So this change should be in close relation to how your application code works.
Hope this helps.
I had this problem in laravel migration too
the order of drop tables in down() method does matter
Schema::dropIfExists('groups');
Schema::dropIfExists('contact');
may not work, but if you change the order, it works.
Schema::dropIfExists('contact');
Schema::dropIfExists('groups');
if you need to support client as soon as possible, and do not have access to
FOREIGN_KEY_CHECKS
so that data integrity can be disabled:
1) delete foreign key
ALTER TABLE `advertisers`
DROP FOREIGN KEY `advertisers_ibfk_1`;
2) activate your deleting operation thruogh sql or api
3) add the foreign key back to schema
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`);
however, it is a hot-fix, so it is on your own risk, because the main flaw of such approach is that it is needed afterwards to keep the data integrity manually.
You could create a trigger to delete the referenced rows in before deleting the job.
DELIMITER $$
CREATE TRIGGER before_jobs_delete
BEFORE DELETE ON jobs
FOR EACH ROW
BEGIN
delete from advertisers where advertiser_id=OLD.advertiser_id;
END$$
DELIMITER ;
The main problem with this erorr Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails is that it doesn't let you know which table contains the FK failure, so it is difficult to solve the conflict.
If you use MySQL or similar, I found out that you can create an ER diagram for your database, then you can review and safely remove any conflicts triggering the error.
Use MySQL workbench
Click on Database -> Reverse Engineering
Select a correct connection
Next till the end, remember to select database & tables that need examine
Now you have the ER diagram, you can see which table have FK conflict
Go to phpmyadmin copy your SQL query and paste into the insert query box.Uncheck the enable foreign key check before pressing go. When dropping you can Uncheck the box and proceed to drop the table. Should work
This error can still when working in Symfony with
Doctrine Query Language, i added onDelete in Entity file
/**
* #ORM\ManyToOne(targetEntity=Pricelist::class)
* #ORM\JoinColumn(name="pricelist_id", referencedColumnName="id", onDelete="SET NULL")
*/
Maybe you should try ON DELETE CASCADE
This happened to me as well and due to a dependency and reference from other tables, I could not remove the entry. What I did is, I added a delete column (of type boolean) to the table. The value in that field showed whether the item is marked for deletion or not. If marked for deletion, then it would not be fetched or used, otherwise, it would be used.