Add Foreign Key to existing table - mysql

I want to add a Foreign Key to a table called "katalog".
ALTER TABLE katalog
ADD CONSTRAINT `fk_katalog_sprache`
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;
When I try to do this, I get this error message:
Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150)
Error in INNODB Status:
120405 14:02:57 Error in foreign key constraint of table
mytable.#sql-7fb1_7d3a:
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL:
Cannot resolve table name close to:
(`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL
When i use this query it works, but with wrong "on delete" action:
ALTER TABLE `katalog`
ADD FOREIGN KEY (`Sprache` ) REFERENCES `sprache` (`ID` )
Both tables are InnoDB and both fields are "INT(11) not null". I'm using MySQL 5.1.61. Trying to fire this ALTER Query with MySQL Workbench (newest) on a MacBook Pro.
Table Create Statements:
CREATE TABLE `katalog` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`AnzahlSeiten` int(4) unsigned NOT NULL,
`Sprache` int(11) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `katalogname_uq` (`Name`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC$$
CREATE TABLE `sprache` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Bezeichnung` varchar(45) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `Bezeichnung_UNIQUE` (`Bezeichnung`),
KEY `ix_sprache_id` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

To add a foreign key (grade_id) to an existing table (users), follow the following steps:
ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE users ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

Simply use this query, I have tried it as per my scenario and it works well
ALTER TABLE katalog ADD FOREIGN KEY (`Sprache`) REFERENCES Sprache(`ID`);

Simple Steps...
ALTER TABLE t_name1 ADD FOREIGN KEY (column_name) REFERENCES t_name2(column_name)

FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;
But your table has:
CREATE TABLE `katalog` (
`Sprache` int(11) NOT NULL,
It cant set the column Sprache to NULL because it is defined as NOT NULL.

check this link. It has helped me with errno 150:
http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/
On the top of my head two things come to mind.
Is your foreign key index a unique name in the whole database (#3 in the list)?
Are you trying to set the table PK to NULL on update (#5 in the list)?
I'm guessing the problem is with the set NULL on update (if my brains aren't on backwards today as they so often are...).
Edit: I missed the comments on your original post. Unsigned/not unsigned int columns maybe resolved your case. Hope my link helps someone in the future thought.

How to fix Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150) in mysql.
alter your table and add an index to it..
ALTER TABLE users ADD INDEX index_name (index_column)
Now add the constraint
ALTER TABLE foreign_key_table
ADD CONSTRAINT foreign_key_name FOREIGN KEY (foreign_key_column)
REFERENCES primary_key_table (primary_key_column) ON DELETE NO ACTION
ON UPDATE CASCADE;
Note if you don't add an index it wont work.
After battling with it for about 6 hours I came up with the solution
I hope this save a soul.

MySQL will execute this query:
ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
Cheers!

When you add a foreign key constraint to a table using ALTER TABLE, remember to create the required indexes first.
Create index
Alter table

try all in one query
ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0,
ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

step 1: run this script
SET FOREIGN_KEY_CHECKS=0;
step 2: add column
ALTER TABLE mileage_unit ADD COLUMN COMPANY_ID BIGINT(20) NOT NULL
step 3: add foreign key to the added column
ALTER TABLE mileage_unit
ADD FOREIGN KEY (COMPANY_ID) REFERENCES company_mst(COMPANY_ID);
step 4: run this script
SET FOREIGN_KEY_CHECKS=1;

ALTER TABLE child_table_name ADD FOREIGN KEY (child_table_column) REFERENCES parent_table_name(parent_table_column);
child_table_name is that table in which we want to add constraint.
child_table_column is that table column in which we want to add foreign key.
parent table is that table from which we want to take reference.
parent_table_column is column name of the parent table from which we take reference

this is basically happens because your tables are in two different charsets. as a example one table created in charset=utf-8 and other tables is created in CHARSET=latin1 so you want be able add foriegn key to these tables. use same charset in both tables then you will be able to add foriegn keys. error 1005 foriegn key constraint incorrectly formed can resolve from this

The foreign key constraint must be the same data type as the primary key in the reference table and column

ALTER TABLE TABLENAME ADD FOREIGN KEY (Column Name) REFERENCES TableName(column name)
Example:-
ALTER TABLE Department ADD FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId)

i geted through the same problem. I my case the table already have data and there were key in this table that was not present in the reference table. So i had to delete this rows that disrespect the constraints and everything worked.

Double check if the engine and charset of the both tables are the same.
If not, it will show this error.

Related

Remove primary key(s) - Foreign key constraint is incorrectly formed

I cannot seem to be able to delete primary keys in a table.
All references (FKs) have been removed but it still doesn't let me delete it.
What I'm trying to do is: delete old primary keys to add a new one - but keep the old columns and data (just remove the PK attribute).
What is wrong ?
Table:
CREATE TABLE `employee` (
`User` int(10) unsigned NOT NULL,
`Company` int(10) unsigned NOT NULL,
--unrelated boolean fields
PRIMARY KEY (`User`,`Company`),
KEY `FK_Employee_Company_idx` (`Company`),
CONSTRAINT `FK_Employee_Company` FOREIGN KEY (`Company`) REFERENCES `company` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_Employee_User` FOREIGN KEY (`User`) REFERENCES `user` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Trying to delete:
alter table Employee
drop primary key;
Issue:
Error 1025: Error on rename of '.\DB_NAME#sql-3640_4' to '.\DB_NAME\employee' (errno: 150 "Foreign key constraint is incorrectly formed") SQL Statement: ALTER TABLE DB_NAME.employee DROP PRIMARY KEY
Nothing references this table anymore. I also checked via statements which select from information_schema.key_column_usage but yields no results.
Wasted the last hours on Google but can't seem to figure it out.
And if that would work, adding a new column:
alter table Employee
add column ID int unsigned not null auto_increment primary key;
The index is still needed for the existing FK constraints.
Adding the following index (first) should satisfy that requirement:
CREATE INDEX xxx ON employee (User, Company);
Test case

Add a Foreign Key to a Populated MYSQL table

I need to add a foreign key to a table already populated with data ...
CREATE TABLE `clientes` (
`id_cliente` int(11) NOT NULL,
`id_cashback` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `cashback00` (
`id` int(11) NOT NULL,
`valor` decimal(9,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE clientes ADD CONSTRAINT fk_cliente_cashback FOREIGN KEY (id_cashback) REFERENCES cashback(id)
ALTER TABLE only works if the parent table (customers) is not populated.
If it already has data, how to proceed since ALTER TABLE presents error "error no. 150" Foreign key constraint is incorrectly formed "
The problem is not that the table is populated with data.
The problem is that the column you are referencing, cashback(id), is not the key of that table.
To make a foreign key, the column you reference should be the primary key of the referenced table.
So I reckon you must first do this:
ALTER TABLE cashback00 ADD PRIMARY KEY (id);
But that will not work if you have duplicate values in id. The primary key must be unique.
Also your foreign key needs to reference the table name you used cashback00, not cashback. Unless you also have a table named cashback which you have not shown in your question.
Thanks to everyone for your help, but I managed to solve the problem:
SGBD integrity issue ...
see, if you want to add a foreign key to a populated parent table, the column must also be populated, like this:
UPDATE clientes
SET id_cashback = '1'
WHERE id_cliente >= '1' AND id_cliente <= '3500'
INSERT INTO cashback00 (valor) VALUES (10.00)
ALTER TABLE clientes ADD CONSTRAINT fk_cliente_cashback FOREIGN KEY (id_cashback) REFERENCES cashback(id)

Drop foreign key MySQL does not exist

I have a table in MySQL like this (this is returned from using show create table user_org_contacts):
CREATE TABLE `user_org_contacts` (
`user_org_contacts_id` int(11) NOT NULL AUTO_INCREMENT,
`from_user_id` int(11) DEFAULT NULL,
`to_org_user_id` int(11) DEFAULT NULL,
`suggested_vacancy_id` int(11) DEFAULT NULL,
`contact_date` datetime NOT NULL,
`message` text,
PRIMARY KEY (`user_org_contacts_id`),
KEY `FK_Reference_53` (`from_user_id`),
KEY `FK_Reference_54` (`to_org_user_id`),
KEY `FK_Reference_55` (`suggested_vacancy_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=latin1
I have noticed that my FK_Reference_54 is wrong and points to the wrong table. So I would like to change this one by the correct FK.
This is what I tried:
ALTER TABLE `user_org_contacts`
DROP FOREIGN KEY `FK_Reference_54`;
ALTER TABLE `user_org_contacts`
ADD CONSTRAINT `FK_Reference_54`
FOREIGN KEY (`to_org_user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE;
This produces the following error:
1091 - Can't DROP 'FK_Reference_54'; check that column/key exists
The problem is that you are confusing indexes with primary keys.
The keyword KEY is actually showing you indexes while primary keys use the keywords CONSTRAINT ... FOREIGN KEY ...
Example:
CONSTRAINT `FK_name` FOREIGN KEY (`current_field_name`)
REFERENCES `external_table_name` (`external_field_name`) ON DELETE CASCADE ON UPDATE CASCADE
So in your case, if you want to remove your INDEX you just need to call this query
ALTER TABLE `user_org_contacts`
DROP INDEX `FK_Reference_54`;
Next time I suggest you using some UI for mysql like mysql workbench, with that you would have noticed the issue immediatly.
First Try To remove that column
ALTER TABLE tablename DROP COLUMN columname;
Then:
ALTER TABLE tablename ADD columnname datatype.
Or you can try this Modify option like.
ALTER TABLE tablename MODIFY COLUMN columnname datatype;
Hope This will help you.

Error 1215 Cannot add foreign key constraint

Table CARGO
DROP TABLE IF EXISTS "hibernatecurso"."cargo";
CREATE TABLE "hibernatecurso"."cargo" (
"idcargo" int(11) NOT NULL DEFAULT '0',
"funcao" varchar(45) DEFAULT NULL,
PRIMARY KEY ("idcargo")
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Table EMPREGADO
DROP TABLE IF EXISTS "hibernatecurso"."empregado";
CREATE TABLE "hibernatecurso"."empregado" (
"idempregado" int(11) NOT NULL DEFAULT '0',
"nome" varchar(45) NOT NULL DEFAULT '',
"cargo" varchar(45) NOT NULL DEFAULT '',
PRIMARY KEY ("idempregado"),
KEY "idx_cargo" ("cargo")
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create index in empregado
ALTER TABLE `hibernatecurso`.`empregado` ADD INDEX `idx_cargo`(`cargo`);
Create FK in empregado
ALTER TABLE `hibernatecurso`.`empregado` DROP INDEX `idx_cargo`,
ADD INDEX `idx_cargo`(`cargo`),
ADD CONSTRAINT `FK_empregado_cargo` FOREIGN KEY `FK_empregado_cargo` (`cargo`)
REFERENCES `cargo` (`funcao`)
ON DELETE CASCADE
ON UPDATE CASCADE;
in this part....
Error while executing query.
ALTER TABLE `hibernatecurso`.`empregado` DROP INDEX `idx_cargo`,
ADD INDEX `idx_cargo`(`cargo`),
ADD CONSTRAINT `FK_empregado_cargo` FOREIGN KEY `FK_empregado_cargo` (`cargo`)
REFERENCES `cargo` (`funcao`)
ON DELETE CASCADE
ON UPDATE CASCADE;
MySQL Error Number 1215
Cannot add foreign key constraint
What is causing the error?
I maybe have hard time reading, but I don't see any index on cargo.funcao. This is very probably missing:
ALTER TABLE `hibernatecurso`.`cargo` ADD INDEX `idx_funcao`(`funcao`);
InnoDB permits a foreign key to reference any index column or group of columns.
However, in the referenced table, there must be an
index where the referenced columns are listed as the first columns in
the same order.
http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
I had the same kind of issue and I fixed it by making sure that collation and types matched in both FK and the parent PK.

MySQL Cannot drop index needed in a foreign key constraint

I need to ALTER my existing database to add a column. Consequently I also want to update the UNIQUE field to encompass that new column. I'm trying to remove the current index but keep getting the error MySQL Cannot drop index needed in a foreign key constraint
CREATE TABLE mytable_a (
ID TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;
CREATE TABLE mytable_b (
ID TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;
CREATE TABLE mytable_c (
ID TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;
CREATE TABLE `mytable` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`AID` tinyint(5) NOT NULL,
`BID` tinyint(5) NOT NULL,
`CID` tinyint(5) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `AID` (`AID`,`BID`,`CID`),
KEY `BID` (`BID`),
KEY `CID` (`CID`),
CONSTRAINT `mytable_ibfk_1` FOREIGN KEY (`AID`) REFERENCES `mytable_a` (`ID`) ON DELETE CASCADE,
CONSTRAINT `mytable_ibfk_2` FOREIGN KEY (`BID`) REFERENCES `mytable_b` (`ID`) ON DELETE CASCADE,
CONSTRAINT `mytable_ibfk_3` FOREIGN KEY (`CID`) REFERENCES `mytable_c` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB;
mysql> ALTER TABLE mytable DROP INDEX AID;
ERROR 1553 (HY000): Cannot drop index 'AID': needed in a foreign key constraint
You have to drop the foreign key. Foreign keys in MySQL automatically create an index on the table (There was a SO Question on the topic).
ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1 ;
Step 1
List foreign key ( NOTE that its different from index name )
SHOW CREATE TABLE <Table Name>
The result will show you the foreign key name.
Format:
CONSTRAINT `FOREIGN_KEY_NAME` FOREIGN KEY (`FOREIGN_KEY_COLUMN`) REFERENCES `FOREIGN_KEY_TABLE` (`id`),
Step 2
Drop (Foreign/primary/key) Key
ALTER TABLE <Table Name> DROP FOREIGN KEY <Foreign key name>
Step 3
Drop the index.
If you mean that you can do this:
CREATE TABLE mytable_d (
ID TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;
ALTER TABLE mytable
ADD COLUMN DID tinyint(5) NOT NULL,
ADD CONSTRAINT mytable_ibfk_4
FOREIGN KEY (DID)
REFERENCES mytable_d (ID) ON DELETE CASCADE;
> OK.
But then:
ALTER TABLE mytable
DROP KEY AID ;
gives error.
You can drop the index and create a new one in one ALTER TABLE statement:
ALTER TABLE mytable
DROP KEY AID ,
ADD UNIQUE KEY AID (AID, BID, CID, DID);
A foreign key always requires an index. Without an index enforcing the constraint would require a full table scan on the referenced table for every inserted or updated key in the referencing table. And that would have an unacceptable performance impact.
This has the following 2 consequences:
When creating a foreign key, the database checks if an index exists. If not an index will be created. By default, it will have the same name as the constraint.
When there is only one index that can be used for the foreign key, it can't be dropped. If you really wan't to drop it, you either have to drop the foreign key constraint or to create another index for it first.
Because you have to have an index on a foreign key field you can just create a simple index on the field 'AID'
CREATE INDEX aid_index ON mytable (AID);
and only then drop the unique index 'AID'
ALTER TABLE mytable DROP INDEX AID;
I think this is easy way to drop the index.
set FOREIGN_KEY_CHECKS=0; //disable checks
ALTER TABLE mytable DROP INDEX AID;
set FOREIGN_KEY_CHECKS=1; //enable checks
drop the index and the foreign_key in the same query like below
ALTER TABLE `your_table_name` DROP FOREIGN KEY `your_index`;
ALTER TABLE `your_table_name` DROP COLUMN `your_foreign_key_id`;
Dropping FK is tedious and risky. Simply create the new index with new columns and new index name, such as AID2. After the new Unique Index is created, you can drop the old one with no issue. Or you can use the solution given above to incorporate the "drop index, add unique index" in the same alter table command. Both solutions will work
In my case I dropped the foreign key and I still could not drop the index. That was because there was yet another table that had a foreign key to this table on the same fields. After I dropped the foreign key on the other table I could drop the indexes on this table.
If you are using PhpMyAdmin sometimes it don't show the foreign key to delete.
The error code gives us the name of the foreign key and the table where it was defined, so the code is:
ALTER TABLE your_table DROP FOREIGN KEY foreign_key_name;
You can show Relation view in phpMyAdmin and first delete foreign key. After this you can remove index.
You can easily check it with DBeaver. Example:
As you can see there are 3 FKs but only 2 FK indexes. There is no index for FK_benefCompanyNumber_beneficiaries_benefId as UK index provide uniqueness for that FK.
To drop that UK you need to:
DROP FK_benefCompanyNumber_beneficiaries_benefId
DROP UK
CREATE FK_benefCompanyNumber_beneficiaries_benefId
The current most upvoted answer is not complete.
One needs to remove all the foreign keys whose "source" column is also present in the UNIQUE KEY declaration.
So in this case, it is not enough to remove mytable_ibfk_1 for the error to go away, mytable_ibfk_2 and mytable_ibfk_3 must be deleted as well.
This is the complete answer:
ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1;
ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_2;
ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_3;
Its late now but I found a solution which might help somebody in future.
Just go to table's structure and drop foreign key from foreign keys list. Now you will be able to delete that column.