是否可以在mySQL 5中同时删除表上的所有外键约束?

时间:2009-08-24 16:41:48

标签: mysql foreign-keys

在mySQL 5中,有没有办法使用一个SQL语句删除表上的所有外键约束而不用名称引用它们?

我正在编写数据库更新脚本,不幸的是,有些网站使用“错误”名称创建了约束。我试图避免进入并从数据库中获取实际约束名称并将它们插回到SQL语句中。

5 个答案:

答案 0 :(得分:12)

我有一个类似于Bing的答案的解决方案,但它更进一步是在程序中自动和可重复使用。

DROP PROCEDURE IF EXISTS dropForeignKeysFromTable;

delimiter ///
create procedure dropForeignKeysFromTable(IN param_table_schema varchar(255), IN param_table_name varchar(255))
begin
    declare done int default FALSE;
    declare dropCommand varchar(255);
    declare dropCur cursor for 
        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 = param_table_name
            and table_schema = param_table_schema;

    declare continue handler for not found set done = true;

    open dropCur;

    read_loop: loop
        fetch dropCur into dropCommand;
        if done then
            leave read_loop;
        end if;

        set @sdropCommand = dropCommand;

        prepare dropClientUpdateKeyStmt from @sdropCommand;

        execute dropClientUpdateKeyStmt;

        deallocate prepare dropClientUpdateKeyStmt;
    end loop;

    close dropCur;
end///

delimiter ;

由于预准备语句一次只能处理一个语句,因此该过程使用游标遍历外键并一次执行一个语句。

要在其中一个表上使用该过程,只需使用以下命令,将table_schema和table_name替换为您的值:

call dropForeignKeysFromTable('table_schema', 'table_name');

答案 1 :(得分:7)

这是一个select,它为表上的所有关系创建完整的drop和create语句。不是自动的,但很容易从...复制/粘贴。

SELECT `DROP`,`CREATE` FROM (
SELECT
CONCAT("ALTER TABLE `", `K`.`TABLE_NAME`, "` DROP FOREIGN KEY `", `K`.`CONSTRAINT_NAME`, "`;") "DROP", 
CONCAT("ALTER TABLE `",
`K`.`TABLE_NAME`,
"` ADD CONSTRAINT ",
"`fk_",
`K`.`TABLE_NAME`,
"_",
`K`.`REFERENCED_TABLE_NAME`,
"1",
"` FOREIGN KEY (`",
`K`.`COLUMN_NAME`,
"`) REFERENCES ",
"`",
`K`.`REFERENCED_TABLE_SCHEMA`,
"`.`",
`K`.`REFERENCED_TABLE_NAME`,
"` (`",
`K`.`REFERENCED_COLUMN_NAME`,
"`) ON DELETE ",
`C`.`DELETE_RULE`,
" ON UPDATE ",
`C`.`UPDATE_RULE`,
";") "CREATE" 
FROM `information_schema`.`KEY_COLUMN_USAGE` `K`
LEFT JOIN `information_schema`.`REFERENTIAL_CONSTRAINTS` `C` USING (`CONSTRAINT_NAME`)
WHERE `K`.`REFERENCED_TABLE_SCHEMA` = "your_db"
AND `K`.`REFERENCED_TABLE_NAME` = "your_table") AS DropCreateConstraints

我用它来删除所有关系,改变键上的数据类型,然后恢复与MySQL Workbench的外键名称的关系。可能对某人有所帮助..

答案 2 :(得分:6)

您当然可以选择*表到临时表,删除并重新创建它,然后复制回来。

答案 3 :(得分:6)

在脚本中,如果您只是想绕过约束,可以随时添加SET FOREIGN_KEY_CHECKS = 0.

另外,我总是使用以下方法删除每个约束的约束:

ALTER TABLE <table_name> DROP FOREIGN KEY <key_name>;

我认为你不能一次完成所有这些,我找不到任何能证明你能做到的例子。

答案 4 :(得分:6)

您可以使用这个简单的bash脚本:

执行命令

sh deleteForeignKeys.sh

和deleteForeignKeys.sh是

#!/bin/bash

dbname="databasename"
table="tablename"

mysqlconn="mysql -u username -ppassword -h host"

tableschema=$($mysqlconn -N -e "SHOW CREATE TABLE $dbname.$table")

#Foreign Keys
fks=$(echo $tableschema | grep -oP '(?<=CONSTRAINT `).*?(?=` FOREIGN KEY)')

for fk in $fks; 
do
    # DROP FOREIGN KEY 
    $mysqlconn -e "ALTER TABLE $dbname.$table DROP FOREIGN KEY $fk";
done