在MySql中删除未命名的外键

Ari*_*său 14 mysql foreign-keys

如果创建的外键没有名称,MySql将为其提供默认值.例如,对于表'Test',外键将命名为'test_ibfk_1'.当我通过使用此名称在本地删除外键时,它就像一个魅力,但在开发服务器上它失败了errno:152.

我知道这个名字区分大小写,但无论是大写还是大写,结果都是一样的.

我的问题:依靠默认名称来操纵约束(至少在MySql中)是否安全?

提前致谢!

Dev*_*art 18

您需要知道外键的名称.如果它是在没有名称的情况下创建的,那么名称将自动生成.您应该获得有关外键的信息.

使用其中一个查询获取外键名称 -

SELECT
  constraint_name
FROM
  information_schema.REFERENTIAL_CONSTRAINTS
WHERE
  constraint_schema = <'db_name'> AND table_name = <'table_name'>;


SELECT *
FROM
  information_schema.KEY_COLUMN_USAGE
WHERE
  constraint_schema = <'db_name'> AND table_name = <'table_name'> AND   
  referenced_table_name IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)

...并用于ALTER TABLE <table_name> DROP INDEX <fk_name>;删除外键.

  • 不得不经历这种耐力跋涉,只是为了获得这种查询的fk_name,这是一种耻辱.应该直截了当地说:`ALTER table table_name DROP CONSTRAINT ON col_name`(无论它有什么名称).毕竟,给定密钥只能有一个这样的约束.大家好吗? (5认同)

mir*_*ngu 6

匆忙的读者,不要因为这个答案很长就离开这个答案。你不会找到另一个解决方案,我保证:)

接受的答案不会删除密钥,它只会找到它的名字。要实际删除名称未知的密钥,您需要使用准备好的语句。最通用的解决方案是此脚本,您可以使用五个变量进行自定义:

-- YOU MUST SPECIFY THESE VARIABLES TO FULLY IDENTIFY A CONSTRAINT
SET @table_name = '...';
SET @column_name = '...';
SET @referenced_table_name = '...';
SET @referenced_column_name = '...';
-- make sure to limit queries to a single db schema
SET @db_name = '...'; 

-- find the name of the foreign key and store it in a var
SET @constraint_name = (
    SELECT constraint_name
    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
    WHERE TABLE_NAME = @table_name
        AND COLUMN_NAME = @column_name
        AND CONSTRAINT_SCHEMA = @db_name
        AND referenced_table_name = @referenced_table_name
        AND referenced_column_name = @referenced_column_name);


-- prepare the drop statement in a string and run it
SET @s = concat('alter table ', @table_name, ' drop foreign key ', @constraint_name);

PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Run Code Online (Sandbox Code Playgroud)