2013-06-18 25 views
15

Jestem na bazie danych MySQL.Upuść klucz obcy tylko wtedy, gdy istnieje

Robię to, ale to nie działa.

ALTER TABLE `object` DROP FOREIGN KEY IF EXISTS `object_ibfk_1`; 

Próbowałem umieścić JEŚLI ZNAMIONY, gdzie tylko mogłem. Jak sprawdzić, czy klucz obcy istnieje, zanim go zrzucisz?

Odpowiedz

1

Którą bazę używasz?

Jeśli SQL Server

if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKName]') AND  
parent_object_id = OBJECT_ID('TableName')) 
alter table TableName drop constraint FKName 
+0

używam MySQL, starałem się umieścić to IF EXISTS, gdzie tylko mogłem. Jak sprawdzić, czy klucz obcy istnieje, zanim go zrzucisz? – Creditto

+0

Który silnik pamięci masowej mysql jest używany? MYISAM lub INNODB ?? Jesteś pewien, że nie używasz MYISAM? –

+0

AM przy użyciu silnika magazynowania INNODB w mysql, próbowałem umieścić to IF EXISTS gdziekolwiek mogłem. Jak sprawdzić, czy klucz obcy istnieje, zanim go zrzucisz? – Creditto

7
IF EXISTS(
       SELECT * 
       FROM INFORMATION_SCHEMA.STATISTICS 
       WHERE INDEX_SCHEMA = DATABASE() 
        AND TABLE_NAME='myTable' 
        AND INDEX_NAME = 'myIndex') 
     THEN 

      ALTER TABLE `myTable` DROP FOREIGN KEY `myForeignKey`; 

      ALTER TABLE `myTable` DROP INDEX `myIndex` ; 

     END IF; 

Po utworzeniu klucza obcego, mysql automatycznie utworzyć indeks na kolumnie odwołania. Powyższy przykład pokazuje, jak sprawdzić indeks w INFORMATION_SCHEMA, ale jest znacznie więcej informacji do sprawdzenia w information schema. Twoja nazwa indeksu wskazuje, że została utworzona dla FK, więc najpierw musisz najpierw usunąć FK, a następnie upuścić indeks. Jeśli utworzysz ponownie klucz obcy, mysql utworzy indeks ponownie. Potrzebuje indeksu, aby wymusić integralność referencyjną bez konieczności skanowania tabeli.

Jeśli Twoim zamiarem było utworzenie nowego indeksu zawierającego tę samą kolumnę, musisz najpierw utworzyć ten indeks (z tą kolumną, która będzie używana jako FK, jako pierwsza na liście kolumny określone dla indeksu). Teraz możesz dodać swoją kopię FK i mysql z przyjemnością użyje nowego indeksu bez tworzenia kolejnego.

Edycja: do szybkiego wyświetlania indeksów po prostu wykonuj POKAŻ INDEKSY z myTable;

16

Jeśli chcesz usunąć klucz obcy jeśli istnieje i nie chcą korzystać z procedur można zrobić to w ten sposób (MySQL):

set @var=if((SELECT true FROM information_schema.TABLE_CONSTRAINTS WHERE 
      CONSTRAINT_SCHEMA = DATABASE() AND 
      TABLE_NAME  = 'table_name' AND 
      CONSTRAINT_NAME = 'fk_name' AND 
      CONSTRAINT_TYPE = 'FOREIGN KEY') = true,'ALTER TABLE table_name 
      drop foreign key fk_name','select 1'); 

prepare stmt from @var; 
execute stmt; 
deallocate prepare stmt; 

Jeśli istnieje klucz obcy kładziemy alter table instrukcja w zmiennej, a jeśli nie, umieszczamy fikcyjną instrukcję. A następnie wykonujemy to.

10

Dla większej przydatności do ponownego użytku, rzeczywiście chciałbyś użyć procedury przechowywanej. Uruchom ten kod raz na żądaną DB:

DROP PROCEDURE IF EXISTS PROC_DROP_FOREIGN_KEY; 
    DELIMITER $$ 
    CREATE PROCEDURE PROC_DROP_FOREIGN_KEY(IN tableName VARCHAR(64), IN constraintName VARCHAR(64)) 
    BEGIN 
     IF EXISTS(
      SELECT * FROM information_schema.table_constraints 
      WHERE 
       table_schema = DATABASE()  AND 
       table_name  = tableName  AND 
       constraint_name = constraintName AND 
       constraint_type = 'FOREIGN KEY') 
     THEN 
      SET @query = CONCAT('ALTER TABLE ', tableName, ' DROP FOREIGN KEY ', constraintName, ';'); 
      PREPARE stmt FROM @query; 
      EXECUTE stmt; 
      DEALLOCATE PREPARE stmt; 
     END IF; 
    END$$ 
    DELIMITER ; 

dalszej kolejności, zawsze można zastąpić to:

ALTER TABLE `object` DROP FOREIGN KEY IF EXISTS `object_ibfk_1`; 

z tym:

CALL PROC_DROP_FOREIGN_KEY('object', 'object_ibfk_1'); 

Skrypt powinien następnie uruchomić płynnie czy object_ibfk_1 faktycznie istnieje lub nie.

Wiele kredytu ze względu na: http://simpcode.blogspot.com.ng/2015/03/mysql-drop-foreign-key-if-exists.html

Powiązane problemy