Confusing cannot add foreign key constraint error - mysql

Ok, maybe it's late and I'm being stupid, but I can't seem to figure out why I'm getting a Cannot add Foreign Key Constraint error for the following query
DROP TABLE IF EXISTS People_Lordships;
CREATE TABLE People_Lordships
(
Id INT PRIMARY KEY AUTO_INCREMENT,
PersonId INT NOT NULL,
LordshipId INT NOT NULL,
AssumedDate Date,
AbdicatedDate Date
);
DROP TABLE IF EXISTS People_Lordships_Current;
CREATE TABLE People_Lordships_Current
(
Id INT PRIMARY KEY AUTO_INCREMENT,
People_LordshipsId INT NOT NULL,
LordShipId INT NOT NULL,
CONSTRAINT Fk_People_Lordships_Current_People_LordshipsId_LordshipId
FOREIGN KEY (`LordshipId`,`People_LordshipsId`)
REFERENCES People_Lordships (`LordshipId`,`Id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT UQ_People_Lordships_Current_LordshipId
UNIQUE KEY (`LordshipId`)
);
And yes, it is a database about noble titles... it's a long story

There is no column LordshipId in table People_Lordships.
Your foreign key definition attempts to reference a column that doesn't exist.
REFERENCES People_Lordships (`LordshipId`,`Id`)
^^^^^^^^^^^^

Figured this one out.
It turns out MySQL cannot add a foreign key constraint against a column that is not the first column in an index.
The following will work
DROP TABLE IF EXISTS People_Lordships;
CREATE TABLE People_Lordships
(
Id INT PRIMARY KEY AUTO_INCREMENT,
PersonId INT NOT NULL,
LordshipId INT NOT NULL,
AssumedDate Date,
AbdicatedDate Date,
INDEX Idx_LordshipId (LordshipId)
);
DROP TABLE IF EXISTS People_Lordships_Current;
CREATE TABLE People_Lordships_Current
(
Id INT PRIMARY KEY AUTO_INCREMENT,
People_LordshipsId INT NOT NULL,
LordShipId INT NOT NULL,
CONSTRAINT Fk_People_Lordships_Current_People_LordshipsId_LordshipId
FOREIGN KEY (`LordshipId`,`People_LordshipsId`)
REFERENCES People_Lordships (`LordshipId`,`Id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT UQ_People_Lordships_Current_LordshipId
UNIQUE KEY (`LordshipId`)
);

Related

SQL Foregin key "Does not exist"

I've been trying to connect my tables with with Foregin key, but I always get an error that my veriable does not exists. I set index for my primary key for counting. My code for table with primary key looks like this:
CREATE TABLE data_animal(
name VARCHAR(30) NOT NULL,
birth_date DATE NOT NULL,
sex ENUM('Male', 'Female') NOT NULL,
animal_car ENUM('Brave', 'Lazy', 'Agressive', 'Nice', 'Nervous') NOT NULL,
des VARCHAR (250),
type ENUM('Cat', 'Dog', 'Bird', 'Snake', 'Fish') NOT NULL,
steril ENUM('Yes', 'No') NOT NULL,
Breed VARCHAR(20) NOT NULL,
id_animal INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE INDEX idx_id_animal
ON data_animal (id_animal);
My code for another table where I need id_animal as foregin key is:
CREATE TABLE photo(
id_picture INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
FOREIGN KEY (id_animal) REFERENCES data_animal (id_animal)
);
I tried few defferent approaches how to insert foreign key as:
id_animal int FOREIGN KEY REFERENCES data_animal(id_animal)
or
CREATE TABLE photo(
id_picture INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
FOREIGN KEY (id_animal) REFERENCES data_animal (id_animal)
)ENGINE=INNODB;
or
CONSTRAINT data_animal FOREIGN KEY (id_animal)
REFERENCES data_animal(id_animal)
I always get this error:
(Key column 'id_animal' doesn't exist in table)
I don't know what else could be wrong. Thanks for the help.
The foreign key has to be a column in the table you're defining, so you need to add an id_animal column to the photos table before you can make it a foreign key.
CREATE TABLE photo(
id_picture INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
id_animal INT,
FOREIGN KEY (id_animal) REFERENCES data_animal (id_animal)
);

i am trying to create foreign keys but i got error 1822 .. please see my code below

CREATE TABLE employee(
empid int auto_increment primary key,
empfirstname varchar(200) not null,
emplastname varchar(200) not null,
email varchar(200) not null,
officenumber int not null
);
CREATE TABLE customer(
custid int auto_increment primary key,
firstname varchar(200) not null,
lastname varchar(200) not null,
address varchar(200) not null,
contact varchar(200)
);
CREATE TABLE product(
productid int auto_increment primary key,
productdesc varchar(500) not null,
weight int not null,
unit_cost int not null
);
CREATE TABLE productorder(
productid int,
orderid int,
primary key(productid,orderid),
constraint fk3 foreign key (productid) references product(productid),
constraint fk4 foreign key (orderid) references productorder(orderid)
);
CREATE TABLE salesorder(
salesorderid int auto_increment primary key,
empid int not null,
custid int not null,
orderdate date not null,
shippingmethod varchar (200) not null,
constraint a_fk1 foreign key (empid) references employee(empid),
constraint a_fk2 foreign key (custid) references customer(custid)
);
What is this meant to do?:
constraint fk4 foreign key (orderid) references productorder(orderid)
It's not uncommon for a table to have a foreign key back to its own primary key, such as for records which have a parent/child relationship. But that doesn't seem to be the case here.
More to the point of the error though, this isn't referencing the entire primary key for the target table. That key has two fields:
primary key(productid,orderid)
So the DBMS can't create the foreign key because its structure doesn't match the target primary key.
If you want to create that foreign key, it would need to match. Probably something like this:
constraint fk4 foreign key (productid,orderid) references productorder(productid,orderid)
But it doesn't appear that you need that foreign key at all, because it doesn't seem to make sense in your data model. Instead I suspect orderid might need to be autoincrement and just use the productid foreign key. Something like this:
CREATE TABLE productorder(
orderid int auto_increment primary key,
productid int,
constraint fk3 foreign key (productid) references product(productid)
);
(Note that there could be more changes you'd want to make to your data model. This answer doesn't purport to provide you with a complete production-ready data model, just to correct the error. Your data model is likely to change/evolve as you develop your system.)
Its normal,
The foreign key in table **productorder**
is refereing to the table itself:
constraint fk4 foreign key (orderid) references **productorder**(orderid)
In order to achieve the self-referencing constraint on the table productorder, you need to add another column with the same type and make typical referencing.
For instance :
Create table productorder (
productid int,
orderid int,
orderid_parent int,
primary key(productid,orderid),
constraint fk_self foreign key(orderid) references productorder(orderid_parent)
)

foreign key constraint fails when drop table from database

I've created 3 tables using the query bellow. But when I try to drop the LOANACCOUNT table I receive an error:
Error:
Error Code: 1217. Cannot delete or update a parent row: a foreign key constraint fails
Create tables queries:
CREATE TABLE LOANACCOUNT
(
ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
LOANACCOUNTTYPE VARCHAR(9) NOT NULL,
CREATIONDATE DATE NOT NULL,
CONSTRAINT LOAN_ACCOUNT_PK PRIMARY KEY (ID),
);
CREATE TABLE TRANSACTIONS
(
ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
ACCOUNTID INT UNSIGNED NOT NULL,
TRANSACTIONTYPE VARCHAR(12) NOT NULL,
CONSTRAINT TRANSACTION_PK PRIMARY KEY (ID),
FOREIGN KEY LOANACCOUNT_FK (ACCOUNTID) REFERENCES LOANACCOUNT (ID) ON DELETE CASCADE
);
CREATE TABLE INSTALLMENT
(
ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
ACCOUNTID INT UNSIGNED NOT NULL,
DUEDATE DATE NOT NULL,
CONSTRAINT INSTALLMENT_PK PRIMARY KEY (ID),
FOREIGN KEY LOANACCOUNT_FK (ACCOUNTID) REFERENCES LOANACCOUNT (ID) ON DELETE CASCADE
);
Drop table query:
DROP TABLE IF EXISTS LOANACCOUNT;
I know that there is something wrong with my foreign keys, but I don't know how to fix it.
As #Rigg Suggested need to drop other table before dropping LOANACCOUNT.
(i.e.) Parent table can't be drop unless there is no child linked.
For time being you can disable foreign key check and then drop those tables.
SET SESSION foreign_key_checks = 0;
DROP TABLE IF EXISTS LOANACCOUNT;
SET SESSION foreign_key_checks = 1;

Cannot add foreign key constraint on a simple code help please

i am trying something apparently simple, but i just keep having the same error "Cannot add foreign key constraint", can anyone help me? I am using workbench with sql
drop table if exists table2;
create table if not exists table2(
id_kind int not null,
id_bod int not null,
id_doc int not null,
primary key (id_kind, id_bod, id_doc)
)engine=InnoDB default charset=latin1;
drop table if exists table1;
create table if not exists table1(
id_mov int not null,
id_kind int not null,
id_prod int,
id_bod int not null,
id_doc int not null,
primary key (id_mov),
key id_kind (id_kind),
key id_bod (id_bod),
key id_doc (id_doc),
foreign key table1 (id_kind) references table2 (id_kind),
foreign key table1 (id_bod) references table2 (id_bod),
foreign key table1 (id_doc) references table2 (id_doc)
)engine=InnoDB default charset=latin1;
I'm pretty sure you are trying to add the foreign key constraint to the wrong table.
Presumably table2 contains the kinds that are referenced by table1.
You'll have to reorder your code, id_kind should probably be the primary key for table2 and you need an index on id_kind in table1:
drop table if exists table2;
create table if not exists tabla2(
id_kind int not null,
primary key (id_kind)
)engine=InnoDB default charset=latin1;
drop table if exists table1;
create table if not exists table1(
id_mov int not null,
id_kind int not null,
id_prod int,
primary key (id_mov),
key id_kind (id_kind),
foreign key table1_ibfk_1 (id_kind) references table2 (id_kind)
)engine=InnoDB default charset=latin1;
UPDATE
It now looks like you want a composite foreign key, try this for your table1:
drop table if exists table1;
create table if not exists table1(
id_mov int not null,
id_kind int not null,
id_prod int,
id_bod int not null,
id_doc int not null,
primary key (id_mov),
key id_kind_id_bod_id_doc (id_kind, id_bod, id_doc),
foreign key table1_ibfk_1 (id_kind, id_boc, id_doc)
references table2 (id_kind, id_boc, id_doc),
)engine=InnoDB default charset=latin1;
I'm still not sure what each of these tables represent, or what you are trying to achieve.
You use the KEY (synonym for INDEX) line to set up an INDEX in your table that the FOREIGN KEY uses.
FOREIGN KEY docs

Can two columns from one table have a foreign key to the same column in another table?

I have two tables in a database, Person and Pet.
CREATE TABLE Person (
id INT NOT NULL,
PRIMARY KEY (id)
)
CREATE TABLE Pet (
id INT NOT NULL,
original_owner INT NOT NULL,
current_owner INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (original_owner)
REFERENCES Person(id),
FOREIGN KEY (current_owner)
REFERENCES Person(id)
)
I am trying to reference the previous owner, and the current owner for each pet. I have also tried
CREATE TABLE Pet (
id INT NOT NULL,
original_owner INT NOT NULL,
current_owner INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (original_owner, current_owner)
REFERENCES Person(id, id)
)
and
CREATE TABLE Pet (
id INT NOT NULL,
original_owner INT NOT NULL,
current_owner INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (original_owner, current_owner)
REFERENCES Person(id)
)
but I get the following error:
Error Code: 1215. Cannot add foreign key constraint
Is this even possible to accomplish? Or would I have to create some sort of bridge table to accommodate this?
Please try the following:
CREATE TABLE IF NOT EXISTS `pet` (
`id` int(11) NOT NULL,
`original_owner` int(11) NOT NULL,
`current_owner` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `origin` (`original_owner`),
KEY `current` (`current_owner`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `pet`
ADD CONSTRAINT `pet_ibfk_2` FOREIGN KEY (`current_owner`) REFERENCES `person` (`id`),
ADD CONSTRAINT `pet_ibfk_1` FOREIGN KEY (`original_owner`) REFERENCES `person` (`id`);
The problem was the order I had the tables defined in the script. I had Pet come before Person. Once I put Person above Pet it worked fine. The example in the question was written from my head, as I didn't have the actual code handy when I posted it.