How to update foreign key value in mysql database - mysql

I have three tables: categories, languages and categories_languages. Categories_languages is many to many table which links together categories and languages. I would like to update a foregin key value in table languages but it throws me error #1451 - Cannot delete or update a parent row: a foreign key constraint fails!
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(11) unsigned NOT NULL auto_increment,
`name` varchar(20) NOT NULL,
`modified` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `languages` (
`id` char(2) NOT NULL,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `categories_languages` (
`id` int(11) unsigned NOT NULL auto_increment,
`category_id` int(11) unsigned NOT NULL,
`language_id` char(2) NOT NULL,
`translation` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_category_id_language_id` (`category_id`,`language_id`),
KEY `fk_language_id` (`language_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
ALTER TABLE `categories_languages`
ADD CONSTRAINT `categories_languages_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `categories_languages_ibfk_2` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE;
The error is clear to me, but how can I update a key value in this case? I tried adding ON UPDATA CASCADE:
ALTER TABLE `categories_languages`
ADD CONSTRAINT `categories_languages_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `categories_languages_ibfk_2` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
but that also fails with message: MySQL said: Documentation #1005 - Can't create table './db_dodo/#sql-c2f_80e6f.frm' (errno: 121)

You can temporarily suspend foreign key checking:
SET foreign_key_checks = 0;
UPDATE languages SET id='xyz' WHERE id='abc';
UPDATE categories_languages SET language_id='xyz' WHERE language_id='abc';
SET foreign_key_checks = 1;
EDIT: As for the foreign key problem: is the data stored on a local or a remote file system? errno 121 is EREMOTEIO (Remote I/O error). Perhaps there are permission problems on the target file system or it doesn't support the # character in filenames?

If you are looking for a temp solution you can also change the ON UPDATE action to CASCADE and modify your ids

Related

Drop a table with foreign key to it fails even with foreign_key_checks=0

I need to run drop table pages when other table has foreign key to it.
CREATE TABLE `pages` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uri` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `pages_domain_unique` (`domain`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
The referencing table:
CREATE TABLE `link_data` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`page_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `link_data_page_id_foreign` (`page_id`),
CONSTRAINT `link_data_page_id_foreign` FOREIGN KEY (`page_id`) REFERENCES `pages` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
The script...
SET foreign_key_checks = 0;
drop table drop table pages; --// the row I am failing with.
ALTER TABLE link_dataDROP FOREIGN KEY link_data_page_id_foreign;
ALTER TABLE link_data DROP COLUMN page_id;
SET foreign_key_checks = 1;
I need to drop the table pages before i remove the referencing field. (complicated issue, dont asy why).
Why foreign_key_checks=0 is not acting in this situation?
Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: DROP TABLEpag
es;)
UPDATE
the question is more about why the foreign_key_checks=0 not affecting the script. How to solve it its simple, just prioritise the script differently.
Thanks
Have you tried set the cascade options ?
CONSTRAINT `link_data_page_id_foreign` FOREIGN KEY (`page_id`) REFERENCES `pages` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
If not, try to declare the constraint as deferrable. When deleting the register itself, set deferred mode and then back.
If you were using phpMyAdmin go to the Variables section and disable foreign key checks to see whether this works.

Cannot add or update a child row: a foreign key constraint fails in mysql phpmyadmin

I have my database named bookedscheduler and when I was to import an sql file an error like this occurs.
Cannot add or update a child row: a foreign key constraint fails (`bookedscheduler`.`group_roles`, CONSTRAINT `group_roles_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `roles` (`role_id`) ON DELETE CASCADE ON UPDATE CASCADE)
Here's my code for the table 'roles' part:
DROP TABLE IF EXISTS `roles`;
CREATE TABLE `roles` (
`role_id` tinyint(2) unsigned NOT NULL,
`name` varchar(85),
`role_level` tinyint(2) unsigned,
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8;
Here's the code for table 'user_roles':
DROP TABLE IF EXISTS `group_roles`;
CREATE TABLE `group_roles` (
`group_id` smallint(8) unsigned NOT NULL,
`role_id` tinyint(2) unsigned NOT NULL,
PRIMARY KEY (`group_id`, `role_id`),
INDEX (`group_id`),
FOREIGN KEY (`group_id`)
REFERENCES groups(`group_id`)
ON UPDATE CASCADE ON DELETE CASCADE,
INDEX (`role_id`),
FOREIGN KEY (`role_id`)
REFERENCES roles(`role_id`)
ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8;

SQLSTATE[HY000] error when creating a table?

This is my SQL:
CREATE TABLE mytable (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(10) NOT NULL,
`token` varchar(100),
`created_at` datetime,
PRIMARY KEY (`id`),
CONSTRAINT `FK_PASSWORD_RECOVERY_CUSTOMER` FOREIGN KEY (`customer_id`) REFERENCES `customer_entity` (`entity_id`) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
Its always giving me: Can't create table 'mytable' (errno: 150) SQL.sql
As posted in my comment to your question, the error you are getting has to do with the constraint definition. You should then check the proper syntax for the constraint.
I think the problem is that you are not indexing the customer_id column. Try to index it:
CREATE TABLE mytable (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(10) NOT NULL,
`token` varchar(100),
`created_at` datetime,
PRIMARY KEY (`id`),
INDEX cust_id(customer_id), -- ADD THIS
FOREIGN KEY (`customer_id`)
REFERENCES `customer_entity` (`entity_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
(just as a precaution and dumb-check, verify that customer_entity is also an InnoDB table)

MySQL Error : #1005 - Can't create table (errno: 150) When I try create more than 1 FK

I have this table:
CREATE TABLE IF NOT EXISTS `produtos` (
`id` int(11) NOT NULL auto_increment,
`idcatprodutos` int(11) NOT NULL,
`idcategoria` int(11) NOT NULL,
`idmarca` int(11) NOT NULL,
`nome` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_produtos_2` (`idcatprodutos`),
KEY `FK_produtos_3` (`idmarca`),
KEY `FK_produtos_4` (`idcategoria`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC AUTO_INCREMENT=39 ;
and this table:
CREATE TABLE IF NOT EXISTS `sugestoes` (
`id` int(11) NOT NULL auto_increment,
`idproduto` int(11) NOT NULL,
`idsugestao1` int(11) NOT NULL,
`idsugestao2` int(11) NOT NULL,
`idsugestao3` int(11) NOT NULL,
`idsugestao4` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_sugestoes_prod` (`idproduto`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED AUTO_INCREMENT=9 ;
I already have created a fk sugestoes.idproduto -> produtos.id working, but I want each of the other fields also refer to the produtos.id through new FK.
Run this command below that return MySQL Error : #1005 - Can't create table (errno: 150):
ALTER TABLE `infantile`.`sugestoes` ADD CONSTRAINT `FK_sugestoes_2` FOREIGN KEY `FK_sugestoes_2` (`idsugestao1`)
REFERENCES `produtos` (`id`)
ON DELETE SET NULL
ON UPDATE CASCADE
, ROW_FORMAT = FIXED;
Does anyone have any idea what's going on?
Try this,
it works:
ALTER TABLE `sugestoes`
ADD CONSTRAINT `FK_idproduto_produtos_1` FOREIGN KEY (`idproduto`) REFERENCES `produtos` (`id`),
ADD CONSTRAINT `FK_sugestoes_produtos_2` FOREIGN KEY (`idsugestao1`) REFERENCES `produtos` (`id`),
ADD CONSTRAINT `FK_sugestoes_produtos_3` FOREIGN KEY (`idsugestao2`) REFERENCES `produtos` (`id`),
ADD CONSTRAINT `FK_sugestoes_produtos_4` FOREIGN KEY (`idsugestao3`) REFERENCES `produtos` (`id`),
ADD CONSTRAINT `FK_sugestoes_produtos_5` FOREIGN KEY (`idsugestao4`) REFERENCES `produtos` (`id`)
UPDATE:
You can not specify
ON DELETE SET NULL
Because of this:
You have defined a SET NULL condition though some of the
columns are defined as NOT NULL
You can see exact error when you run
SHOW ENGINE INNODB STATUS;
Perhaps removing the ROW_FORMAT = FIXED:
ALTER TABLE `infantile`.`sugestoes`
ADD CONSTRAINT `FK_sugestoes_2`
FOREIGN KEY `FK_sugestoes_2` (`idsugestao1`)
REFERENCES `produtos` (`id`)
ON DELETE SET NULL
ON UPDATE CASCADE
;
On second thought, how do you expect the ON DELETE SET NULL to behave when your column is defined with NOT NULL ?
And third, does the table has any data in it? If some of the rows violate this FK constraint, then you can't create that FK.

Constraint violation on insert

With the following tables
CREATE TABLE `Play` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`room_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IDX_FEBB7184A76ED395` (`user_id`),
KEY `IDX_FEBB718454177093` (`room_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE `User` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`nickname` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_2DA17977F85E0677` (`username`),
UNIQUE KEY `UNIQ_2DA17977A188FE64` (`nickname`),
UNIQUE KEY `UNIQ_2DA17977E7927C74` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
INSERT INTO `User` VALUES(1, 'user', 'nickname', 'user#user.de');
CREATE TABLE `Room` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
INSERT INTO `Room` VALUES(1);
ALTER TABLE `Play`
ADD CONSTRAINT `play_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`),
ADD CONSTRAINT `play_ibfk_2` FOREIGN KEY (`room_id`) REFERENCES `Room` (`id`);
And trying to run the following statement
INSERT INTO `Play` (`id` ,`user_id` ,`room_id`) VALUES (NULL , '1', '1')
I get an error
#1452 - Cannot add or update a child row: a foreign key constraint fails
(`play`, CONSTRAINT `play_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`))
Both data sets, #1 of User and #1 of Room exist in the databse. How can this fail? I am quite familiar with SQL, but I have no idea what the error is in this case...
Fixed it. It was an issue that only comes up when using MySQL 5.5.9, InnoDB and Mac OS X 10.6
See: MySQL Bug #60309
I changed the .conf of MySQL to add this line:
[mysqld]
lower_case_table_names=1
And it works now. Thanks for your help anyway.
The problem lies only in the order in which you are executing the queries. The tables "User" and "Room" must be defined before you create a foreign key constraint on them.