2012-12-05 17 views
16

外部キーにより、新しい要件を満たすためにデータベース構造を変更するには多すぎる問題が発生します - プライマリキーを変更したいのですが、外部キーが問題のテーブルを参照するときMySQLはテーブルを削除して再作成するためだと思います)。MYSQLデータベース内のすべての外部キーを削除する

私はDBで作業している間に、すべての外部キーを削除して後で再作成したいと考えています。そうするためのきちんとした方法はありますか?

+0

だけでテストされていないと思ったが、何にはInnoDBからテーブルの変更についてMyISAM?変換バックは難しいかもしれませんが... – Sablefoste

+0

OffTopic?データベース開発はもうSOの一部ではありませんか? –

答えて

25

あなたは、単にあなたが作るしようとしている任意のテーブルの変更文の前に次のコマンドを発行することができます

SET foreign_key_checks = 0; 

これは、データベース接続のための外部キー制約のチェックをオフにします。制約を心配することなく変更を加えることができます。

あなたが行われた後、発行することを忘れないでください:

SET foreign_key_checks = 1; 

が背中にそれらを有効にします。

これでも、列データ型が一致しないために失敗する新しい外部キー制約を作成できないことに注意してください。

+1

それは完璧な、感謝の音! –

27

実行

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; 

と出力を実行します。手順でも

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; 

+0

_出力を実行するにはどうすればよいですか?例えばスクリプト内 –

+0

@LightnessRacesinOrbit出力をSQLファイルにリダイレクトし、ファイルを実行します。 – Zoozy

+3

そして、出力をSQLファイルにリダイレクトする方法と、SQL文内の_fromファイルを実行する方法はありますか? –

2

Zoozyコードの別のバージョン、ここであなただけのテーブルを選択することができます

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/// 
関連する問題