Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drop unnamed Foreign Key in MySql

If a foreign key was created without a name, MySql will give it a default one. For instance, for table 'Test' the foreign key will be named 'test_ibfk_1'. When I drop the foreign key locally by using this name it works like a charm but on the development server it fails with errno: 152.

I know this name is case sensitive but either lower or upper case the result is the same.

My question: Is it safe to rely on the default name to manipulate constraints (in MySql at least)?

Thanks in advance!

like image 472
Ariel Chelsău Avatar asked Dec 13 '12 09:12

Ariel Chelsău


People also ask

How do I get rid of unnamed foreign key?

You could remove without know the name, creating a concatenate query and executing automatically: set @s:=''; select @s:=concat(@s, 'alter table ', 'your_table', ' drop foreign key ',CONSTRAINT_NAME, ';') from information_schema.

How do you drop unnamed constraints?

First, inspect the name given to the FK by the RDBMS, it has the same prefix and body but differs only in suffix hash. Second, select names of these constraints. Third, exec alter command that drops them.


3 Answers

You need to know the name of foreign key. If it was created without name, then name will be autogenerated. You should get information about the foreign key.

Use one of these queries to get foreign key names -

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;

...and use ALTER TABLE <table_name> DROP INDEX <fk_name>; to drop foreign key.

like image 116
Devart Avatar answered Oct 11 '22 02:10

Devart


Hurried reader, don't go away from this answer, just because it's long. You won't find another solution, I promise :)

The accepted answer does not drop the key, it only finds its name. To actually drop the key with an unknown name, you'll need to use prepared statements. The most general solution is this script that you can customize with five variables:

-- 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;
like image 24
mircealungu Avatar answered Oct 11 '22 02:10

mircealungu


You could remove without know the name, creating a concatenate query and executing automatically:

set @s:='';
select @s:=concat(@s, 'alter table ', 'your_table', ' drop foreign key ',CONSTRAINT_NAME, ';')
from information_schema.key_column_usage
where CONSTRAINT_SCHEMA = 'your_database'
  and TABLE_NAME ='your_table'
  and REFERENCED_TABLE_NAME = 'the_foreign_reference_table';
prepare stmt from @s;
execute stmt;

deallocate prepare stmt;

I that way you don't need to know the name of the foreign key, only need the table_name which you want to remove the foreign key, the database name and the reference table.

like image 44
jose miguel rivera rodríguez Avatar answered Oct 11 '22 00:10

jose miguel rivera rodríguez