我接手了一个项目,有相同issue的部分主键被签名,相关的外域也被签名。
我使用了@Devart 方法,但我能够自动化整个过程。我能够查询information_schema
生成额外的 SQL 语句,我可以“剪切和粘贴”然后运行。
生成 SQL 语句以删除所有约束
SELECT concat('ALTER TABLE ', TABLE_NAME, ' DROP FOREIGN KEY ', CONSTRAINT_NAME, ';')
FROM information_schema.key_column_usage
WHERE CONSTRAINT_SCHEMA = 'YOUR_SCHEMA_NAME'
AND referenced_table_name IS NOT NULL;
更改任何id
需要更改为 UNSIGNED 的列
SELECT
CONCAT('ALTER TABLE `', TABLE_NAME, '` CHANGE COLUMN id id INT UNSIGNED NOT NULL AUTO_INCREMENT;')
FROM `COLUMNS`
WHERE
`COLUMN_KEY` = 'PRI' AND
`TABLE_SCHEMA` = 'YOUR_SCHEMA_NAME' AND
`COLUMN_TYPE` NOT LIKE '%unsigned%' AND
`COLUMN_TYPE` LIKE '%int%' AND
`COLUMN_NAME` = 'id';
更改指向的外部字段id
SELECT CONCAT('ALTER TABLE `', kcu.TABLE_NAME, '` CHANGE COLUMN ', kcu.COLUMN_NAME,' ', kcu.COLUMN_NAME, ' INT UNSIGNED ', IF(c.IS_NULLABLE = 'YES', 'NULL', 'NOT NULL'), ';')
FROM `KEY_COLUMN_USAGE` kcu
INNER JOIN `COLUMNS` c
ON
kcu.TABLE_NAME = c.TABLE_NAME AND
kcu.COLUMN_NAME = c.COLUMN_NAME
WHERE
`REFERENCED_COLUMN_NAME` = 'id' AND
`REFERENCED_TABLE_NAME` IN (
SELECT
TABLE_NAME
FROM `COLUMNS`
WHERE
`COLUMN_KEY` = 'PRI' AND
`TABLE_SCHEMA` = 'YOUR_SCHEmA_NAME' AND
`COLUMN_TYPE` NOT LIKE '%unsigned%' AND
`COLUMN_TYPE` LIKE '%int%' AND
`COLUMN_NAME` = 'id'
);
(请注意,在此声明中,即使它们已经是 UNSIGNED,也会被错误地更改为 UNSIGNED,但这不会导致任何问题)
重新插入所有必需的约束
SELECT CONCAT('ALTER TABLE ', rc.`TABLE_NAME` ,' ADD CONSTRAINT ', rc.`CONSTRAINT_NAME`, ' FOREIGN KEY (',kcu.`COLUMN_NAME`,') REFERENCES ', rc.`REFERENCED_TABLE_NAME` ,'(id) ON DELETE ', DELETE_RULE , ' ON UPDATE ' , UPDATE_RULE, ';')
FROM `REFERENTIAL_CONSTRAINTS` rc
INNER JOIN
`KEY_COLUMN_USAGE` kcu
ON rc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
WHERE kcu.CONSTRAINT_SCHEMA = 'api' AND
kcu.`REFERENCED_COLUMN_NAME` = 'id';
密切注意这些 SQL 语句,可能需要针对您的模式进行修改,例如,它假定您的主 id 称为“id”。
此外,您必须在运行它们的任何实际输出之前运行所有 4 个语句。
使用 MySQL 5.6