2013-06-18 5 views
15

Я нахожусь в базе данных MySQL.Отключить внешний ключ, только если он существует

Я делаю это, но это не работает.

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

Я попытался поместить это IF EXISTS везде, где мог. Как проверить, существует ли внешний ключ перед его удалением?

ответ

1

Какую базу данных вы используете?

Если 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

Am использованием MYSQL, я попытался поставить это IF EXISTS, где бы я мог. Как проверить, существует ли внешний ключ перед его удалением? – Creditto

+0

Какой двигатель хранения mysql вы используете? MYISAM или INNODB ?? Вы уверены, что не используете MYISAM? –

+0

AM, используя механизм хранения INNODB в mysql, я попытался поместить этот IF EXISTS, где мог. Как проверить, существует ли внешний ключ перед его удалением? – 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; 

При создании внешнего ключа, MySQL автоматически создает индекс на указанной колонке. В приведенном выше примере показано, как проверить индекс в INFORMATION_SCHEMA, но есть гораздо больше информации для вас, чтобы проверить в information schema. Ваше имя индекса указывает на то, что оно было создано для FK, поэтому вам придется сначала отказаться от FK, а затем отбросить индекс. Если вы снова создадите внешний ключ, mysql снова создаст индекс. Он нуждается в индексе для обеспечения ссылочной целостности без необходимости выполнять сканирование таблицы.

Если вы намеревались создать новый индекс, содержащий один и тот же столбец, сначала необходимо создать этот индекс (с этим столбцом, который будет использоваться как FK, первым в списке столбцы, указанные для индекса). Теперь вы можете добавить свой FK обратно, и mysql будет рад использовать новый индекс, не создавая другого.

Редактировать: для быстрого просмотра индексов просто выполните ПОКАЖИТЕ ИНДЕКСЫ из myTable;

16

Если вы хотите отказаться от внешнего ключа, если он существует, и не хочет использовать процедуры вы можете сделать это следующим образом (для 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; 

Если есть внешний ключ мы помещаем изменить таблицу в переменной, и если мы не добавим фиктивный оператор. И затем мы его выполним.

10

Для большей повторной юзабилити, вы действительно захотите использовать хранимую процедуру. Выполнить этот код один раз на нужной БД:

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 ; 

После этого, вы всегда можете заменить это:

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

с этим:

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

Ваш скрипт должен затем работать бесперебойно ли object_ibfk_1 на самом деле существует или нет.

Много кредита из: http://simpcode.blogspot.com.ng/2015/03/mysql-drop-foreign-key-if-exists.html

Смежные вопросы