Is it possible to cascade delete from same MySQL table? I want to cascade delete in a table that references itself in relations.
Example:
I have a comments table that has comment_id and parent_id, where parent_id is the same id in comment_id.
Parent_id could be either another comment_id or null if it's a root
comment.
I want to be able to select any node in this tree and delete it. In the process, all child nodes and sub-child nodes should be deleted.
I have tried to alter my table using this query
ALTER TABLE `comment`
ADD FOREIGN KEY (`comment_id`)
REFERENCES `comment`(`parent_id`) ON DELETE CASCADE ON UPDATE RESTRICT;
but I end up with an error
Cannot add or update a child row: a foreign key constraint fails
(zendaya001.#sql-6c1_1044ab, CONSTRAINT comment_ibfk_3 FOREIGN
KEY (comment_id) REFERENCES comment (parent_id) ON DELETE
CASCADE ON UPDATE RESTRICT)
For reproduction, this is my comment table:
CREATE TABLE `comment` (
`comment_id` int NOT NULL,
`post_id` int UNSIGNED NOT NULL,
`user_id` int NOT NULL,
`parent_id` int DEFAULT NULL,
`content` text NOT NULL,
`type` varchar(50) DEFAULT NULL,
`count_replies` int NOT NULL DEFAULT '0',
`count_likes` int NOT NULL DEFAULT '0',
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for table `comment`
--
ALTER TABLE `comment`
ADD PRIMARY KEY (`comment_id`),
ADD KEY `user_id` (`user_id`),
ADD KEY `post_id` (`post_id`),
ADD KEY `parent_id` (`parent_id`);
You try to create the foreign key with incorrect direction.
Must be:
ALTER TABLE `comment`
ADD FOREIGN KEY (`parent_id`)
REFERENCES `comment`(`comment_id`) ON DELETE CASCADE ON UPDATE RESTRICT;
https://dbfiddle.uk/iJRlziwL
comment_id must be defined at least UNIQUE (maybe PRIMARY KEY).
I cannot insert a new record into the table even if ON UPDATE RESTRICT is also set to CASCADE – Freesoul
You do something wrongly.
https://dbfiddle.uk/rcUupB2b
Related
I keep getting errors when importing my old SQL file and fix them all,but I'm stuck and can't understand what this means.
ALTER TABLE property ADD CONSTRAINT property_ibfk_1 FOREIGN KEY
(intid) REFERENCES interiors (id) ON DELETE CASCADE ON UPDATE
CASCADE, ADD CONSTRAINT property_ibfk_2 FOREIGN KEY (owner)
REFERENCES accounts (id) ON DELETE SET NULL ON UPDATE CASCADE
MySQL said: Documentation
1452 - Cannot add or update a child row: a foreign key constraint fails (ionicnew.#sql-252c_e1, CONSTRAINT property_ibfk_2 FOREIGN
KEY (owner) REFERENCES accounts (id) ON DELETE SET NULL ON
UPDATE CASCADE)
Full code of property table:
CREATE TABLE `property` (
`id` int(11) NOT NULL,
`x` float NOT NULL,
`y` float NOT NULL,
`z` float NOT NULL,
`a` float NOT NULL,
`type` bit(32) NOT NULL,
`intid` int(11) NOT NULL,
`name` varchar(128) NOT NULL,
`price` int(11) NOT NULL,
`mapicon` tinyint(3) UNSIGNED NOT NULL,
`status` tinyint(3) UNSIGNED NOT NULL,
`point` int(10) UNSIGNED NOT NULL,
`saleprice` int(11) NOT NULL DEFAULT '0',
`owner` int(11) DEFAULT NULL,
`money` int(11) NOT NULL DEFAULT '0',
`level` tinyint(3) UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `property`
ADD PRIMARY KEY (`id`),
ADD KEY `intid` (`intid`),
ADD KEY `owner` (`owner`);
ALTER TABLE `property`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=86;
ALTER TABLE `property`
ADD CONSTRAINT `property_ibfk_1` FOREIGN KEY (`intid`) REFERENCES `interiors` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `property_ibfk_2` FOREIGN KEY (`owner`) REFERENCES `accounts` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
I can upload the full SQL file if needed.
Foreign key relationships involve a parent table that holds the
central data values, and a child table with identical values pointing
back to its parent. The FOREIGN KEY clause is specified in the child
table.
It will reject any INSERT or UPDATE operation that attempts to create
a foreign key value in a child table if there is no a matching
candidate key value in the parent table.
To know more Go to this link
So your error Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails essentially means that, you are trying to add a row to your property table for which no matching row (intid) is present in interiors table.
You must first insert the row to your interiors table.
I've recently started trying to use foreign keys to make database management easier on myself. I'm having a terrible time trying to figure out how they actually work, and most of the time I can get it working between tables without issue. But I'm currently having an issue with 2 of my tables, and I can't figure it out.
I'm getting an error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(REDACTED.rc_logs, CONSTRAINT rc_logs_ibfk_1 FOREIGN
KEY (user_id) REFERENCES rc_teammates (uid) ON DELETE CASCADE ON
UPDATE CASCADE)
[/home5/redacted/public_html/redacted/rc/public/assets/php/connection.php:25]
but my tables seem to be set up properly, and I'm really confused about why it's not working. Here is my table structures:
rc_teammates
CREATE TABLE `rc_teammates` (
`uid` int(11) NOT NULL,
`name` text NOT NULL,
`primary_line` int(11) NOT NULL,
`hireStatus` text NOT NULL,
`created_on` date NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `rc_teammates`
ADD PRIMARY KEY (`uid`), ADD UNIQUE KEY `uid` (`uid`), ADD KEY `primary_line` (`primary_line`), ADD KEY `primary_line_2` (`primary_line`);
ALTER TABLE `rc_teammates`
MODIFY `uid` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `rc_teammates`
ADD CONSTRAINT `rc_teammates_ibfk_1` FOREIGN KEY (`primary_line`) REFERENCES `rc_lines` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE;
rc_logs
CREATE TABLE IF NOT EXISTS `rc_logs` (
`uid` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`line` int(11) NOT NULL,
`date` date NOT NULL,
`type` varchar(15) NOT NULL,
`timein` time NOT NULL,
`timeout` time NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=latin1;
ALTER TABLE `rc_logs`
ADD PRIMARY KEY (`uid`), ADD KEY `user_id` (`user_id`), ADD KEY `line` (`line`), ADD KEY `user_id_2` (`user_id`);
ALTER TABLE `rc_logs`
MODIFY `uid` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=53;
ALTER TABLE `rc_logs`
ADD CONSTRAINT `rc_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `rc_teammates` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `rc_logs_ibfk_2` FOREIGN KEY (`line`) REFERENCES `rc_lines` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE;
I've tried to look up the error, and I've had this issue before but I do not remember how I solved it. What's worse is, this was working earlier, until I emptied the rc_teammates table to start fresh.
I really cannot figure this out, and would love any pointers. Thanks!
As you said you have "emptied" (TRUNCATE?) the table rc_teammates.
And you try to insert a record in rc_logs, and this record has a user_id that doesn't exists in rc_teammates, thus violation of the following constraint:
ADD CONSTRAINT `rc_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `rc_teammates` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
Just add a record in rc_teammates, having a uid equal to the user_id of the record you are trying to insert in rc_logs, and retry.
Also, about this :
ALTER TABLE `rc_teammates`
ADD PRIMARY KEY (`uid`), ADD UNIQUE KEY `uid` (`uid`),
ALTER TABLE `rc_teammates`
MODIFY `uid` int(11) NOT NULL AUTO_INCREMENT;
When you set a column as PRIMARY KEY, it is de facto : UNIQUE, NOT NULL and INDEXED. You don't need to specify all this, PRIMARY KEY is enough. This is valid for your other table as well.
CREATE TABLE `class` (
`class_id` int(11) NOT NULL AUTO_INCREMENT,
`section_name` varchar(50) NOT NULL,
`class_alias` varchar(200) NOT NULL,
`grading_scheme` int(11) NOT NULL DEFAULT '0',
`year` year(4) NOT NULL,
`grade_calc_method_id` varchar(20) DEFAULT NULL,
PRIMARY KEY (`class_id`)
) ENGINE=InnoDB AUTO_INCREMENT=48819 DEFAULT CHARSET=latin1;
CREATE TABLE `teachers` (
`teacher_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`teacher_subject` varchar(20) NOT NULL DEFAULT 'None',
PRIMARY KEY (`teacher_id`),
KEY `user_id` (`user_id`,`school_id`)
) ENGINE=InnoDB AUTO_INCREMENT=48606 DEFAULT CHARSET=latin1;
CREATE TABLE `teacher_classes` (
`teacher_class_id` int(11) NOT NULL AUTO_INCREMENT,
`teacher_id` int(11) NOT NULL,
`class_id` int(11) NOT NULL,
PRIMARY KEY (`teacher_class_id`),
UNIQUE KEY `teacher_id_class_id` (`teacher_id`,`class_id`),
KEY `teacher_id` (`teacher_id`,`class_id`)
) ENGINE=InnoDB AUTO_INCREMENT=46707 DEFAULT CHARSET=latin1;
Trying to insure data consistency between the tables by using foreign key so that the DBMS can check for errors.I have another junction table teacher_classes
Here is my query to add foreign keys constraint
ALTER TABLE teacher_classes
ADD CONSTRAINT `tc_fk_class_id` FOREIGN KEY (`class_id`)
REFERENCES class (`class_id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
ADD CONSTRAINT `tc_fk_teacher_id` FOREIGN KEY (`teacher_id`)
REFERENCES teachers (`teacher_id`) ON UPDATE NO ACTION ON DELETE NO ACTION;
've seen the other posts on this topic, but no luck, getting following error.
Cannot add or update a child row: a foreign key constraint fails
(DB_NAME.#sql-403_12, CONSTRAINT
tc_fk_teacher_id FOREIGN KEY (teacher_id) REFERENCES teachers
(teacher_id) ON DELETE NO ACTION ON UPDATE NO ACTION)
Too late to Answer. I just had the same problem the solution is easy.
You're getting this error because you're trying to or UPDATE a row to teacher_classes doesn't match the id in table teachers.
A simple solution is disable foreign key checks before performing any operation on the table.
SET FOREIGN_KEY_CHECKS = 0;
After you are done with the table enable it again.
SET FOREIGN_KEY_CHECKS = 1;
Or you can remove not null constraint and insert a NULL value in it.
That's most probably the column definition doesn't match properly. For table teachers the PK column definition is as below.
`teacher_id` int(11) NOT NULL AUTO_INCREMENT
Make sure you have the same definition in your child table teacher_classes
I have this table
CREATE TABLE `product_category` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`category_id` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `category_id` (`category_id`),
CONSTRAINT `category_id` FOREIGN KEY (`category_id`) REFERENCES `product_category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
What I'm trying to get is to delete on cascade every record which category_id fields equals to id field, but I cant insert any record, it gives me an error
cannot add or update a child row: a foreign key constraint fails('database/product_category', CONSTRAINT 'category_id FOREIGN KEY('category_id') REFERENCES product_category('id') ON DELETE CASCADE ON UPDATE CASCADE
Your foreigh key value must point to existing product_category (id), but there are no allowable rows in table. So make
category_id int(11) NULL,
instead your definition and insert first row like
INSERT INTO product_category SET name='test1';
I have a custom table created which has a foreign constraint on the core_website table. However, the on delete cascade isn't working.
I did a search and found this relevant thread, which notes that the data types between the two columns have to be the same. Both data types are smallint(5).
I did notice one minor discrepancy in the column definition, which is that in core_website, Allow Null is not set, and Default is not set to zero, whereas in the account table, Allow Null is set and Default is zero. I didn't think changing these would have any effect, but I went ahead and changed them on the account table to match, but that didn't help.
CREATE TABLE `account` (
`account_id` smallint(11) unsigned NOT NULL AUTO_INCREMENT,
`website_id` smallint(5) unsigned DEFAULT '0',
`code` varchar(64) NOT NULL DEFAULT '',
PRIMARY KEY (`account_id`),
UNIQUE KEY `code` (`code`),
KEY `FK_WEBSITE_ID` (`website_id`),
CONSTRAINT `FK_WEBSITE_ID` FOREIGN KEY (`website_id`) REFERENCES `core_website` (`website_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8
try this and let us the result pls.
CREATE TABLE `account` (
`account_id` smallint(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`website_id` smallint(5) unsigned DEFAULT '0',
`code` varchar(64) NOT NULL DEFAULT '',
UNIQUE KEY `code` (`code`),
KEY `FK_WEBSITE_ID` (`website_id`),
CONSTRAINT `FK_WEBSITE_ID` FOREIGN KEY (`website_id`) REFERENCES `core_website` (`website_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8
You need add foreign key to core_website table and point it to website_id field in account table. In other words, foreign key should be added to the dependent table and pointed to main table, in this case when you delete row from main table - row from dependent table will be deleted because of FK. In your case you did it "upside down".