2012-12-05 60 views
16

外鍵導致我修改數據庫結構以滿足新要求時出現太多問題 - 我想修改主鍵,但是當外鍵引用有問題的表時我看不到認爲是因爲MySQL刪除了表並重新創建)。刪除MYSQL數據庫中的所有外鍵

所以,當我在數據庫上工作時,我想簡單地刪除所有外鍵並稍後重新創建它們。有沒有一個乾淨的方式來做到這一點?

+0

只是一個未經測試的想法,但什麼:

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; 
用程序

而且MyISAM數據?雖然轉回可能很難... – Sablefoste

+0

OffTopic?數據庫開發不再是SO的一部分了嗎? –

回答

25

你可以簡單地之前,你做任何ALTER TABLE語句發出以下命令:

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; 

和運行輸出。

+0

_我們可以運行輸出嗎?例如在腳本中 –

+0

@LightnessRacesinOrbit將輸出重定向到一個sql文件,然後運行該文件。 – Zoozy

+3

我們如何將輸出重定向到SQL文件,並在SQL語句中運行_from文件_? –

2

的Zoozy代碼的另一種版本,在這裏你可以只選擇一個表:約從Innodb的改變表來

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