38

我在一个 MySQL 数据库上。

我正在这样做,但它不起作用。

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

我试图把这个 IF EXISTS 放在任何可能的地方。如何在删除之前检查外键是否存在?

4

7 回答 7

30

如果您想删除外键(如果存在)并且不想使用过程,您可以这样做(对于 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;

如果有外键,我们将 alter table 语句放入变量中,如果没有,我们放入一个 dummy 语句。然后我们执行它。

于 2015-06-29T17:12:26.957 回答
19

为了获得更高的可重用性,您确实希望使用存储过程。在所需的数据库上运行此代码一次:

   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

于 2015-12-31T10:35:14.703 回答
14
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 中的索引,但是您可以在信息模式中检查更多信息。您的索引名称似乎表明它是为 FK 创建的,因此您必须先删除 FK,然后删除索引。如果再次创建外键,mysql 将再次创建索引。它需要一个索引来强制引用完整性,而不必进行表扫描。

如果您打算创建一个包含相同列的新索引,则必须首先创建该索引(此列将用作 FK,是为指数)。现在你可以添加你的 FK 并且 mysql 将很乐意使用新索引而不创建另一个索引。

编辑:要快速查看索引,只需执行 SHOW INDEXES FROM myTable;

于 2013-11-05T11:48:24.877 回答
8

在当前版本的 Mariadb 10.1.26(新 Mysql)中,您的查询有效:

钥匙: MUL

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

钥匙: <NULL>

于 2018-07-25T14:59:43.810 回答
2

这是一个解决方法DROP FOREIGN KEY IF EXISTS,它在之前的 MySQL 和 MariaDB 版本中是缺失的v10.1.4。您也可以将它用于您想要的所有其他语句,这应该取决于是否存在FOREIGN KEY(例如,SELECT "info: foreign key exists."在下面的示例中)。

-- DROP FOREIGN KEY IF EXISTS
SELECT
    COUNT(*)
INTO
    @FOREIGN_KEY_my_foreign_key_ON_TABLE_my_table_EXISTS
FROM
    `information_schema`.`table_constraints`
WHERE
    `table_schema` = 'my_database'
    AND `table_name` = 'my_table'
    AND `constraint_name` = 'my_foreign_key'
    AND `constraint_type` = 'FOREIGN KEY'
;
-- SELECT @FOREIGN_KEY_my_foreign_key_ON_TABLE_my_table_EXISTS;
SET @statement := IF(
    @FOREIGN_KEY_my_foreign_key_ON_TABLE_my_table_EXISTS > 0,
    -- 'SELECT "info: foreign key exists."',
    'ALTER TABLE my_table DROP FOREIGN KEY my_foreign_key',
    'SELECT "info: foreign key does not exist."'
);
PREPARE statement FROM @statement;
EXECUTE statement;
于 2018-09-05T16:38:06.307 回答
1

你用的是哪个数据库??

如果 SQL 服务器

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
于 2013-06-18T06:07:06.690 回答
-3

类似的讨论: 只有在 sql server 中存在外键约束时,我如何删除它?

IF (OBJECT_ID('FK_ConstraintName', 'F') IS NOT NULL)

非常有用,这里还没有提到。

于 2015-12-15T20:33:12.143 回答