Error in foreign key constraint on a dropped table - mysql

When I execute the following SQL commands:
CREATE TABLE `TableA` (
`tableAId` INT(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`tableAId`)
);
CREATE TABLE `TableB` (
`tableBId` INT(11) NOT NULL AUTO_INCREMENT,
`tableAId` INT(11) DEFAULT NULL,
PRIMARY KEY (`tableBId`),
CONSTRAINT `FK_TABLE_A_ID` FOREIGN KEY (`tableAId`) REFERENCES `TableA` (`tableAId`)
);
ALTER TABLE `TableB`
RENAME TO `NewTableB`;
ALTER TABLE `TableA`
RENAME TO `NewTableA`,
CHANGE COLUMN `tableAId` `newTableAId` INT(11) NOT NULL AUTO_INCREMENT FIRST;
DROP TABLE IF EXISTS NewTableA;
DROP TABLE IF EXISTS NewTableB;
CREATE TABLE `TableA` (
`tableAId` INT(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`tableAId`)
);
I have the following error on the last command (ie CREATE TABLE TableA (...)) :
Erreur SQL (1005): Can't create table 'TableA' (errno: 150) Foreign
key constraint is incorrectly formed
And when I execute show engine innodb status I have :
------------------------
LATEST FOREIGN KEY ERROR
------------------------
130531 12:06:05 Error in foreign key constraint of table TableB:
there is no index in referenced table which would contain
the columns as the first columns, or the data types in the
referenced table do not match the ones in table. Constraint:
,
CONSTRAINT `FK_TABLE_A_ID` FOREIGN KEY (`tableAId`) REFERENCES `NewTableA` (`tableAId`)

Old question but for others in a similar situation the answer I made at:
https://dba.stackexchange.com/a/87587/56052
may help.
Recreate the table with the same foreign key specification as previous but a
different name.
Drop the resulting table (will also drop original orphan foreign key)
Recreate table with original or no foreign key

Related

How to rename both a primary key and a foreign key connected with each other?

I created two tables and want to set a one_to_many relation.
I firstly created a primary key tappa_id on table 'tappa' and then a foreign key tappa_id connected to the previous one on table low_cost_hotels.
I then changed the name of the table tappa to leg.
I want to rename the primary key in the first table and the foreign key in the second one which refers to it but I always get errors. I wonder whether or not the issue is due to the fact that they're already connected with each other:
I wrote the following code to drop the primary key in the table legs-->
ALTER TABLE legs DROP COLUMN tappa_id ;
And got this error message (FrancigenaApp is the name of the database which contains the tables) ->
ERROR 1025 (HY000): Error on rename of './FrancigenaApp/#sql-33c0_26' to './FrancigenaApp/legs' (errno: 150)
I wrote the following code to drop the foreign key connected to the previous (tappa_id) in the table low_cost_hotels:
ALTER TABLE low_cost_hotels DROP FOREIGN KEY tappa_id;
and got the error:
ERROR 1025 (HY000): Error on rename of './FrancigenaApp/low_cost_hotels' to
'./FrancigenaApp/#sql2-33c0-27' (errno: 152)
I suppose I need to drop the foreign key before renaming the primary key but I can't do that and it doesn't seem to be an error in the SQL syntax...
This works for me, even without disabling foreign key checks:
Initial schema:
create table parent (
parent_id int,
data text,
primary key (parent_id)
);
create table child (
child_id int,
parent_id int,
data text,
primary key (child_id),
foreign key (parent_id) references parent(parent_id)
);
insert into parent (parent_id, data) values (1, 'data');
insert into child (child_id, parent_id, data) values (1, 1, 'data');
Rename parent_id to parent_id_new in both tables;
alter table child change parent_id parent_id_new int;
alter table parent change parent_id parent_id_new int;
Check the schema:
show create table parent;
show create table child;
Result is:
CREATE TABLE `parent` (
`parent_id_new` int(11) NOT NULL,
`data` text,
PRIMARY KEY (`parent_id_new`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `child` (
`child_id` int(11) NOT NULL,
`parent_id_new` int(11) DEFAULT NULL,
`data` text,
PRIMARY KEY (`child_id`),
KEY `parent_id` (`parent_id_new`),
CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id_new`) REFERENCES `parent` (`parent_id_new`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
View on DB Fiddle
In MySQL 8 you can use RENAME COLUMN syntax:
alter table child rename column parent_id to parent_id_new;
alter table parent rename column parent_id to parent_id_new;

Cannot truncate a table referenced in a foreign key constraint from empty table

I have the following tables:
CREATE TABLE `companies_investorfundinground` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`funding_round_id` int(11) NOT NULL,
`investor_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `companies_funding_round_id_8edc4cc4_fk_companies_fundinground_id` (`funding_round_id`),
KEY `companies_investor_investor_id_30d4fd3e_fk_companies_investor_id` (`investor_id`),
CONSTRAINT `companies_funding_round_id_8edc4cc4_fk_companies_fundinground_id` FOREIGN KEY (`funding_round_id`) REFERENCES `companies_fundinground` (`id`),
CONSTRAINT `companies_investor_investor_id_30d4fd3e_fk_companies_investor_id` FOREIGN KEY (`investor_id`) REFERENCES `companies_investor` (`id`)
)
CREATE TABLE `companies_fundinground` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`funding_round_code` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `companies_fundinground_447d3092` (`company_id`),
CONSTRAINT `companies_company_id_36dd5970_fk_companies_company_entity_ptr_id` FOREIGN KEY (`company_id`) REFERENCES `companies_company` (`entity_ptr_id`)
)
I was able to truncate companies_investorfundinground.
I try to delete companies_fundinground but I get the error:
Cannot truncate a table referenced in a foreign key constraint companies_funding_round_id_8edc4cc4_fk_companies_fundinground_id
Why am I getting this error if companies_investorfundinground is completely truncated?
TRUNCATE TABLE is equivalent to dropping the table and recreating it as a new table. This would break the foreign key reference.
It says in https://dev.mysql.com/doc/refman/5.7/en/truncate-table.html:
Logically, TRUNCATE TABLE is similar to a DELETE statement that deletes all rows, or a sequence of DROP TABLE and CREATE TABLE statements. To achieve high performance, it bypasses the DML method of deleting data. Thus, it cannot be rolled back, it does not cause ON DELETE triggers to fire, and it cannot be performed for InnoDB tables with parent-child foreign key relationships.
Consider this another way: if TRUNCATE TABLE is supposed to be fast and efficient, is it worth spending the time to check a child table to see if it has any referencing rows? That table might have millions of rows, but have NULL in its foreign key column on all rows.
If you know for certain that you won't upset the child table, you have a workaround:
mysql> create table p ( id int primary key );
mysql> create table f ( pid int, foreign key (pid) references p(id));
mysql> truncate table p;
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
(`test`.`f`, CONSTRAINT `f_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `test`.`p` (`id`))
mysql> set foreign_key_checks=0;
mysql> truncate table p;
mysql> set foreign_key_checks=1;

"Cannot add foreign key constraint" error in MySQL 5.6.16 in very simple case of two tables: Why?

Here is the exact SQL I attempt to execute (using SQLYog as a MySQL client on Windows):
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` INT (11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE = INNODB ;
DROP TABLE IF EXISTS `temp`;
CREATE TEMPORARY TABLE `temp` (
dish_id INT (11) NOT NULL,
user_id INT (11) NOT NULL,
UNIQUE KEY (dish_id, user_id),
FOREIGN KEY `test` (dish_id) REFERENCES test (id)
) ENGINE = INNODB ;
Here is the exact error received upon the attempt to create temp:
Error Code: 1215
Cannot add foreign key constraint
It looks to me like everything is in order - the data type and signed-ness of the two related keys is the same; the names appear to be kosher; what is going on?
What am I doing wrong? Why is the foreign key constraint failing to be created?
It's because you're trying to add a foreign key constraint to a temporary table.
From the manual:
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. The parent and child tables must use the same storage engine.
They must not be TEMPORARY tables.
http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html
EDIT:
Try it with a permanent table. It works.
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` INT (11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE = INNODB ;
DROP TABLE IF EXISTS `temp`;
CREATE TABLE `temp` (
dish_id INT (11) NOT NULL,
user_id INT (11) NOT NULL,
UNIQUE KEY (dish_id, user_id),
FOREIGN KEY `test` (dish_id) REFERENCES test (id)
) ENGINE = INNODB ;

Drop Column with foreign key in MySQL

I have the following 2 tables:
CREATE TABLE `personal_info` (
`p_id` int(11) NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`initials` text NOT NULL,
`surname` text NOT NULL,
`home_lang` int(11) NOT NULL,
PRIMARY KEY (`p_id`),
KEY `home_lang` (`home_lang`),
CONSTRAINT `personal_info_ibfk_1` FOREIGN KEY (`home_lang`) REFERENCES `language_list` (`ll_id`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=latin1
CREATE TABLE `language_list` (
`ll_id` int(11) NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
PRIMARY KEY (`ll_id`)
) ENGINE=InnoDB AUTO_INCREMENT=73 DEFAULT CHARSET=latin1
I am trying to remove a column from a table with the following:
ALTER TABLE `personal_info` DROP `home_lang`
But cannot do it since I recieve this error:
#1025 - Error on rename of '.\MyDB\#sql-112c_82' to '.\MyDB\personal_info' (errno: 150)
I have tried to first remove the index and then remove the column with this:
ALTER TABLE personal_info DROP INDEX home_lang
But then I get the following error:
#1553 - Cannot drop index 'home_lang': needed in a foreign key constraint
So I tried to drop the foreign key:
ALTER TABLE personal_info DROP FOREIGN KEY home_lang
But received this error:
#1025 - Error on rename of '.\MyDB\personal_info' to '.\MyDB\#sql2-112c-8d' (errno: 152)
I have also tried to first set all the values to null:
update personal_info set home_lang = null
But then received this error:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`MyDB`.`personal_info`, CONSTRAINT `personal_info_ibfk_1` FOREIGN KEY (`home_lang`) REFERENCES `language_list` (`ll_id`))
And now I am stuck. I have tried a few things but just cannot get the column removed. I am not allowed to alter the DB in any way other than removing the column.
Your DROP FOREIGN KEY syntax is using the wrong key name. It's trying to drop your "plain" index on the home_lang field. It's NOT the foreign key itself.
CONSTRAINT `personal_info_ibfk_1` FOREIGN KEY (`home_lang`) REFERENCES `language_list` (`ll_id`)
^^^^^^^^^^^^^^^^^^^^^--- THIS is the name of the foreign key
Try:
ALTER TABLE personal_info DROP FOREIGN KEY `personal_info_ibfk_1`
Use this given below query to find the name of the foreign key.
SHOW CREATE TABLE forms_main;
Then once u got the key, execute drop foreign key command
alter TABLE `forms_main`
drop FOREIGN key `forms_main_ibfk_1`;
Then execute the drop column command
ALTER TABLE `forms_main` DROP `company_id`;
ALTER TABLE db_name.table_name
DROP FOREIGN KEY foreign_key;
ALTER TABLE test.exam
DROP INDEX id ;

MySQL (InnoDB): need to delete column, and accompanying foreign key constraint and index

Here's my table:
CREATE TABLE `alums_alumphoto` (
`id` int(11) NOT NULL auto_increment,
`alum_id` int(11) NOT NULL,
`photo_id` int(11) default NULL,
`media_id` int(11) default NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `alums_alumphoto_alum_id` (`alum_id`),
KEY `alums_alumphoto_photo_id` (`photo_id`),
KEY `alums_alumphoto_media_id` (`media_id`),
CONSTRAINT `alums_alumphoto_ibfk_1` FOREIGN KEY (`media_id`) REFERENCES `media_mediaitem` (`id`),
CONSTRAINT `alum_id_refs_id_706915ea` FOREIGN KEY (`alum_id`) REFERENCES `alums_alum` (`id`),
CONSTRAINT `photo_id_refs_id_63282119` FOREIGN KEY (`photo_id`) REFERENCES `media_mediaitem` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=63 DEFAULT CHARSET=utf8
I want to delete the column photo_id, which presumably will also require deleting the foreign key constraint and the index.
The problem is that I get errors when I try to drop the column:
ERROR 1025 (HY000): Error on rename of '.\dbname\#sql-670_c5c' to '.\dbname\alums_alumphoto' (errno: 150)
... when I try to drop the index (same as above), and when I try to drop the foreign key constraint:
ERROR 1091 (42000): Can't DROP 'photo_id_refs_id_63282119'; check that column/key exists)
What order should I be doing all of this in? What precise commands should I be using?
Precisely, try this :
First drop the Foreign Key or Constraint :
ALTER TABLE `alums_alumphoto` DROP FOREIGN KEY `photo_id_refs_id_63282119`;
The previous command removes the Foreign Key Constraint on the column. Now you can drop the column photo_id (the index is removed by MySQL on dropping the column) :
ALTER TABLE `alums_alumphoto` DROP COLUMN `photo_id`;
Aternatively, you could combine these 2 operations into one :
ALTER TABLE `alums_alumphoto`
DROP FOREIGN KEY `photo_id_refs_id_63282119` ,
DROP COLUMN `photo_id`;
The sure thing is to make a duplicate table.
> CREATE TABLE alums_alumphoto_new LIKE alums_alumphoto;
> ALTER TABLE .... // Drop constraint
> ALTER TABLE .... // Drop KEY
> ALTER TABLE .... // Drop the column
> INSERT INTO alums_alumphoto_new (SELECT id, alum_id, photo_id, media_id, updated FROM alums_alumphoto);
> RENAME TABLE alums_alumphoto TO alums_alumphoto_old, alums_alumphoto_new TO alums_alumphoto;
If there's an error executing RENAME TABLE, some other tables might have foreign key constraints referencing this table, in which case this whole approach is stupid. :)
Try combining the DROP KEY and DROP FOREIGN KEY statements.
ALTER TABLE `alums_alumphoto`
DROP KEY KEY `alums_alumphoto_photo_id`,
DROP FOREIGN KEY `photo_id_refs_id_63282119`;
ALTER TABLE `alums_alumphoto`
DROP COLUMN `photo_id`;