I am writing a script to upgrade an old version of my schema to a newer version. The script is a series of MySQL commands within an .sql
file.
One of the changes I need to make is to recreate a foreign key following the renaming of the table to which it refers. e.g.:
CREATE TABLE foo (
`key` INT UNSIGNED NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=InnoDB;
CREATE TABLE `bar` (
`key` INT UNSIGNED NOT NULL,
`fk` INT UNSIGNED NOT NULL,
PRIMARY KEY (`key`),
FOREIGN KEY (`fk`) REFERENCES `foo` (`key`) ON DELETE CASCADE
) ENGINE=InnoDB;
becomes:
CREATE TABLE `foo2` (
`key` INT UNSIGNED NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=InnoDB;
CREATE TABLE `bar` (
`key` INT UNSIGNED NOT NULL,
`fk` INT,
PRIMARY KEY (`key`),
FOREIGN KEY `fk1` (`fk`) REFERENCES `foo2` (`key`) ON DELETE CASCADE
) ENGINE=InnoDB;
Renaming foo
to foo2
is easy, but updating that foreign key in bar
is not so much. I cannot simply name the foreign key in an ALTER TABLE
statement because the old schema failed to name it, and I do not wish to try to "guess" at the automatically-generated substitute.
I found the following which will generate the statement I need in order to drop the key entirely (later recreating it as needed):
SELECT CONCAT(
'ALTER TABLE ',
`table_schema`, '.', `table_name`,
' DROP FOREIGN KEY ', `constraint_name`, ';'
)
FROM `information_schema`.`table_constraints`
WHERE `constraint_type` = 'FOREIGN KEY'
AND `table_name` = 'bar';
but how can I actually execute the result of that, from within my upgrade script? Or can I solve the problem better?