2012-12-05 16 views
16

Klucze obce powodują zbyt wiele problemów modyfikujących strukturę bazy danych, aby spełnić nowe wymagania - Chcę zmodyfikować klucze główne, ale wydaje mi się, że nie mogę, gdy klucze obce odnoszą się do danej tabeli (I myśleć, ponieważ MySQL opuszcza tabelę i tworzy ją ponownie).Zrzuć wszystkie klucze obce w bazie danych MySQL

Podczas pracy nad DB chciałbym po prostu usunąć wszystkie klucze obce i odtworzyć je później. Czy jest jakiś sposób na zrobienie tego?

+0

Just an niesprawdzone myśli, ale co zmienia tabele z InnoDB do MyISAM? Chociaż powrót do konwersji może być trudny ... – Sablefoste

+0

OffTopic? Rozwój bazy danych nie jest już częścią SO? –

Odpowiedz

25

Można po prostu wydać następujące polecenia przed wszelkimi sprawozdania alter table masz zamiar zrobić:

SET foreign_key_checks = 0; 

To wyłączy klucz obcy kontrole ograniczenie dla połączenia z bazą danych. Następnie możesz wprowadzić zmiany bez obawy o ograniczenia.

Po skończeniu, nie zapomnij do wydawania:

SET foreign_key_checks = 1; 

Aby włączyć je ponownie.

Należy zauważyć, że nadal nie będzie można utworzyć nowego ograniczenia klucza obcego, który zakończyłby się niepowodzeniem, ponieważ typy danych kolumn nie są zgodne.

+1

Brzmi idealnie, dzięki! –

27

Run

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; 

i uruchomić produkcję.

+0

_Jak_ możemy uruchomić wyjście? na przykład w skrypcie –

+0

@LightnessRacesinOrbit Przekieruj dane wyjściowe do pliku sql i uruchom plik. – Zoozy

+3

A w jaki sposób przekierowujemy dane wyjściowe do pliku SQL i uruchamiamy plik, _z wewnątrz instrukcji SQL_? –

2

Inna wersja kodu Zoozy, tutaj można wybrać tylko stół:

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; 

Również z procedurą:

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