【问题标题】:DROP all foreign keys in MYSQL database删除 MYSQL 数据库中的所有外键
【发布时间】:2012-12-05 22:02:59
【问题描述】:

外键导致我在修改数据库结构以满足新要求时遇到太多问题 - 我想修改主键,但当外键引用有问题的表时我似乎不能(我认为是因为 MySQL 删除了表并且重新创建)。

因此,当我在数据库上工作时,我想简单地删除所有外键并稍后重新创建它们。有没有一种巧妙的方法?

【问题讨论】:

  • 只是一个未经测试的想法,但是将表从 Innodb 更改为 MyISAM 怎么样?虽然转换回来可能很困难......

标签: mysql


【解决方案1】:

运行

SELECT concat('ALTER TABLE ', TABLE_NAME, ' DROP FOREIGN KEY ', CONSTRAINT_NAME, ';') 
FROM information_schema.key_column_usage 
WHERE CONSTRAINT_SCHEMA = 'db_name' 
AND referenced_table_name IS NOT NULL;

并运行输出。

【讨论】:

  • 如何运行输出?例如在脚本中
  • 我们如何将输出重定向到 SQL 文件并运行该文件,在 SQL 语句中?
  • 这似乎是正确的答案,但由于某种原因,这会导致我的 MySQL 服务器进程崩溃。
  • 我知道这已经很晚了,但是在 MySQL Workbench 上工作我只需要运行上面的查询并将输出复制粘贴到一个新脚本中并运行该脚本。这就是我“将输出重定向到 sql 文件”的方式。
  • 这对我很有用。为了补充这个答案,我有一些语句在结果中出现了两次或更多次,所以我在字段中添加了AS statement,并在 SELECT 语句的末尾添加了GROUP BY statement。
【解决方案2】:

另一个版本的Zoozy代码,这里只能选择一个表:

SELECT concat('ALTER TABLE ', TABLE_NAME, ' DROP FOREIGN KEY ', CONSTRAINT_NAME, ';') 
FROM information_schema.key_column_usage 
WHERE CONSTRAINT_SCHEMA = 'YOUR DB HERE' 
AND TABLE_NAME='YOUR TABLE HERE' 
AND REFERENCED_TABLE_NAME IS NOT NULL;

还有一个过程:

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///

【讨论】:

    【解决方案3】:

    您可以在要进行任何 Alter Table 语句之前简单地发出以下命令:

    SET foreign_key_checks = 0;
    

    这将关闭您的数据库连接的外键约束检查。然后,您可以进行更改而无需担心限制。

    完成后别忘了发出:

    SET foreign_key_checks = 1;
    

    重新打开它们。

    请注意,这仍然不允许您创建新的外键约束,该约束会因为列数据类型不匹配而失败。

    【讨论】:

      【解决方案4】:

      如果你想跨多个数据库做同一张表,别忘了在输出中输入CONSTRAINT_SCHEMA:

      SELECT concat('ALTER TABLE ', CONSTRAINT_SCHEMA,'.',TABLE_NAME, ' DROP FOREIGN KEY ', CONSTRAINT_NAME, ';')
      FROM information_schema.key_column_usage
      WHERE CONSTRAINT_SCHEMA like 'your_db_prefix_%'
          AND TABLE_NAME='your_table'
          AND REFERENCED_TABLE_NAME IS NOT NULL;
      

      【讨论】:

        猜你喜欢
        • 2013-01-10
        • 1970-01-01
        • 2014-04-13
        • 2020-06-23
        • 1970-01-01
        • 2018-01-15
        • 1970-01-01
        • 2014-02-09
        • 1970-01-01
        相关资源
        最近更新 更多