Error
Error renaming ... errno: 150 - foreign key constraint is not correctly formed)
happens because you are trying to delete the referenced primary key, even if you disable the check of foreign key constraints with SET FOREIGN_KEY_CHECKS=0;
Disabling foreign key verification will allow you to temporarily delete a row in the currency table or add an invalid currencyId to the foreign key tables, but not discard the primary key.
Changing the PRIMARY KEY that other tables are already referencing will not be easy, since you risk losing the referential integrity between the tables and losing the connection between the data. To save data, you need a process, for example:
- Add a new foreign key column (
code ) to each FK table - Match the foreign key
code with the previous currencyId using update - Discard existing foreign key
- Discard old column
currencyId - After all FKs have been reset, change the primary key in the
currency table - Recover foreign keys based on new
code column
This will be done below without having to disable FOREIGN_KEY_CHECKS , but the foreign key step / drop / rereate must be repeated for all tables that reference currency :
-- Add new FK column ALTER TABLE FKTable ADD currencyCode char(3) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL; -- Map FK column to the new Primary Key UPDATE FKTable SET currencyCode = (SELECT `code` FROM currency WHERE id = FKTable.currencyId); -- Drop the old foreign key + column ALTER TABLE FKTable DROP FOREIGN KEY FKTable_Currency; ALTER TABLE FKTable DROP COLUMN currencyId; -- Once the above is done for all FK tables, drop the PK on currency ALTER TABLE `currency` CHANGE COLUMN `id` `id` INT(11) NOT NULL, DROP PRIMARY KEY; ALTER TABLE currency ADD PRIMARY KEY (`code`); ALTER TABLE FKTable ADD CONSTRAINT FKTable_Currency2 FOREIGN KEY (currencyCode) REFERENCES currency(`code`);
SqlFiddle here
source share