I have 2 unrelated tables but each one has the same column type I called 'somefield'
CREATE TABLE `table1` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`somefield` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`),
)
CREATE TABLE `table2` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`somefield` int(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`)
)
After I insert into either of these tables, I insert into this table the 'somefield' value.
CREATE TABLE `table3` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`somefield` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`),
CONSTRAINT `FK_table3` FOREIGN KEY (`somefield`) REFERENCES `table1` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE
)
At the moment, if i delete a row in table1, the same row is deleted in table3. I can insert into table1 and do an insert on table3 without any problems but if i insert into table2 and try to insert into table3 i get this error
Integrity constraint violation: 1452 Cannot add or update a child row:
a foreign key constraint fails
I know this is to do with the foreign key constraint in that it expects the 'somefield' value to be present in table1. What I want to know is how to add another constraint.
ALTER TABLE table3 ADD CONSTRAINT FK_table3 FOREIGN KEY (`somefield`) REFERENCES `table2` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE;
Would i need to create 2 tables to act as a go between for table1/table3 and table2/table3?
I was able to sort this by creating a table which the other 3 tables all link to.
If a row is deleted in the new table, the resulting rows are deleted in the other tables.
CREATE TABLE IF NOT EXISTS `table1` (
`id` tinyint(3) NOT NULL AUTO_INCREMENT,
`somefield` varchar(12) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`)
);
CREATE TABLE IF NOT EXISTS `table2` (
`id` tinyint(3) NOT NULL AUTO_INCREMENT,
`somefield` varchar(12) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`)
);
CREATE TABLE IF NOT EXISTS `table3` (
`id` tinyint(3) NOT NULL AUTO_INCREMENT,
`somefield` varchar(12) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`)
);
CREATE TABLE IF NOT EXISTS `supertable` (
`somefield` varchar(12) NOT NULL DEFAULT '',
PRIMARY KEY (`somefield`),
UNIQUE KEY `somefield` (`somefield`)
);
ALTER TABLE `table1`
ADD CONSTRAINT `FK_table1` FOREIGN KEY (`somefield`) REFERENCES `supertable` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `table2`
ADD CONSTRAINT `FK_table2` FOREIGN KEY (`somefield`) REFERENCES `supertable` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `table3`
ADD CONSTRAINT `FK_table3` FOREIGN KEY (`somefield`) REFERENCES `supertable` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE;
Related
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
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';
-- Constraints for table `variation`
--
ALTER TABLE `variation`
ADD FOREIGN KEY (`parent`) REFERENCES `variation` (`id`),
ADD FOREIGN KEY (`scale`) REFERENCES `scale` (`id`),
ADD FOREIGN KEY (`user`) REFERENCES `users` (`user_id`);
--
error
ERROR 1452 (23000) at line 277: Cannot add or update a child row: a
foreign key constraint fails (getsy.#sql-f44_2a, CONSTRAINT
#sql-f44_2a_ibfk_2 FOREIGN KEY (scale) REFERENCES scale (id))
this table variation
CREATE TABLE IF NOT EXISTS `variation` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`parent` bigint(20) DEFAULT NULL,
`scale` bigint(20) DEFAULT NULL,
`value` varchar(255) NOT NULL,
`user` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `parent` (`parent`,`scale`,`value`,`user`),
KEY `scale` (`scale`),
KEY `user` (`user`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=101 ;
help me ..
thanks
Looks like that in variation table column scale contains values that are missing in table scale column id.
You can check missing values with following query:
SELECT DISTINCT a.scale FROM
variation AS a LEFT JOIN scale AS b ON a.scale = b.id
WHERE b.id IS NULL;
I'm building a table with a two part foreign key that references a two part key in another table. It isn't working, and I can't see why because the data types line up.
Can't create table 'tsugi.video_comments' (errno: 150)
Here's the code I'm trying to run:
CREATE TABLE `video_comments` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
`videoTime` int(11) NOT NULL,
`comment` text NOT NULL,
`parent` int(11) unsigned DEFAULT NULL,
`private` tinyint(1) DEFAULT NULL,
`replies` int(11) unsigned DEFAULT '0',
`reports` int(11) DEFAULT '0',
`user_id` int(11) NOT NULL,
`displayname` varchar(2048) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `video_ibfk_1` (`link_id`),
KEY `video_ibfk_2` (`user_id`),
CONSTRAINT `video_comments_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `video_comments` (`id`) ON DELETE CASCADE,
CONSTRAINT `video_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `lti_link` (`link_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `video_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `lti_user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `video_key` FOREIGN KEY (`link_id`, `video_id`) REFERENCES `video_ids` (`link_id`, `video_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=285 DEFAULT CHARSET=utf8;
The command runs successfully if I delete the last constraint, so that's where the problem is, not in the other constraints.
Here's the table it's referencing:
CREATE TABLE `video_ids` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `video_key` (`video_id`,`id`),
KEY `link_id` (`link_id`),
KEY `id` (`id`,`video_id`),
CONSTRAINT `video_ids_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `t_lti_link` (`link_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
To make sure that the video_id and link_id fields are exactly the same, I copied them directly from the existing table's code to the code for creating the new table. I expected that to solve it, but it did not. Here's the error log:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
141114 22:04:09 Error in foreign key constraint of table tsugi/video_comments:
FOREIGN KEY (`link_id`, `video_id`) REFERENCES `video_ids` (`link_id`, `video_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=285 DEFAULT CHARSET=utf8:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Foreign key references need to be to unique or primary keys. So, you can fix this just by having a unique declaration in video_ids:
CREATE TABLE `video_ids` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `video_key` (`video_id`,`id`),
KEY `link_id` (`link_id`),
KEY `id` (`id`,`video_id`),
UNIQUE (link_id, video_id),
CONSTRAINT `video_ids_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `t_lti_link` (`link_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
Here is a SQL Fiddle with an example.
All I need is to create 2 tabeles with next structure:
The SQL:
CREATE TABLE IF NOT EXISTS `ds_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `module_news_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) NOT NULL,
`cat_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_module_news_cats_module_news_cats` (`parent`),
KEY `fk_module_news_cats_ds_cats1` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
ALTER TABLE `module_news_cats`
ADD CONSTRAINT `fk_module_news_cats_ds_cats1` FOREIGN KEY (`cat_id`) REFERENCES `ds_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_module_news_cats_module_news_cats` FOREIGN KEY (`parent`) REFERENCES `module_news_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
But when I try to insert first row to my table "module_news_cats", I recive next error:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`empty`.`module_news_cats`, CONSTRAINT `fk_module_news_cats_module_news_cats` FOREIGN KEY (`parent`) REFERENCES `module_news_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Question:
How I can create table which will have an index with non-identifying relationship to the anther index in the same table? Some rows will have parents, and some not.
I think you just need to allow NULLs in module_news_cats.parent:
CREATE TABLE IF NOT EXISTS `module_news_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) NULL, -- Change this
`cat_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_module_news_cats_module_news_cats` (`parent`),
KEY `fk_module_news_cats_ds_cats1` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
and then if there isn't a parent, create the row with a NULL in parent.
Your 'parent' field cannot be empty (NULL) if you insert a record, which means that every record you insert should refer to a parent ID (which is impossible if there are no entries in your table yet).
If you make the 'parent' field in the module_news_cats table nullable:
ALTER TABLE `module_news_cats` CHANGE `parent` `parent` INT( 11 ) NULL DEFAULT NULL
you should be able to insert records that have no parent ID associated (just supply NULL instead of a value).
You could make the parent column in the module_news_cats table nullable.
Then for rows that have no parents populate the parent column with null.