我参与的项目是将项目从Oracle迁移到MySQL。我有一个脚本,我正在运行MySQL shell命令,名为CreateTables.sql,内部看起来像这样:
source table\DropForeignKeys.sql
source tables\Site.sql
source tables\Language.sql
source tables\Country.sql
source tables\Locale.sql
source tables\Tag.sql
mysql --user=root --password --database=junkdb -vv < CreateTables.sql
我所追求的是根据db是否有任何表的条件,使第一个脚本DropForeignKeys.sql的执行条件的方法。或者,如果有一种方法可以删除约束(如果不存在),但是根据我的知识在MySQL中不存在这样的构造。
所以我的问题是如何在脚本级别或约束级别下删除外键约束,以便我可以获得可靠的可重放脚本?
答案 0 :(得分:4)
我所追求的是根据数据库是否有任何表格而使第一个脚本DropForeignKeys.sql的执行成为条件的方法。
条件逻辑(IF / ELSE)仅在函数和存储过程中受支持 - 您必须使用类似的东西:
DELIMITER $$
DROP PROCEDURE IF EXISTS upgrade_database $$
CREATE PROCEDURE upgrade_database()
BEGIN
-- INSERT NEW RECORD IF PREEXISTING RECORD DOESNT EXIST
IF((SELECT COUNT(*) AS column_exists
FROM information_schema.columns
WHERE table_name = 'test'
AND column_name = 'test7') = 0) THEN
ALTER TABLE test ADD COLUMN `test7` int(10) NOT NULL;
UPDATE test SET test7 = test;
SELECT 'Altered!';
ELSE
SELECT 'Not altered!';
END IF;
END $$
DELIMITER ;
CALL upgrade_database();
您可以参考INFORMATION_SCHEMA.KEY_COLUMN_USAGE。
,而不是参考INFORMATION_SCHEMA.COLUMNS根据您的需要:
ALTER TABLE [table name] DISABLE KEYS
ALTER TABLE [table name] ENABLE KEYS
...将禁用并重新启用附加到该表的键,而无需了解每个键。您可以使用SET foreign_key_checks = 0;
禁用和启用数据库级别的密钥,并SET foreign_key_checks = 1;
启用它们。
令我惊讶的是,MySQL似乎没有更好的方法来处理这个常见的脚本问题。
Oracle也没有,但是在你不知道细节的情况下,约束并不是你想要盲目改变的。
我需要drop foreign key脚本的原因是drop table在它们是FK附件时会产生错误。禁用FK检查是否允许我放弃表格?
是的,删除或禁用约束将允许您删除表但要注意 - 为了重新启用fk检查,您将需要父级中的数据来匹配子表中的现有数据。 / p>