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!
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.
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.
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.
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;
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With