Cannot add foreign key constraint on a simple code help please - mysql

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

Related

Why does it come up with an error that says that the column doesnt exist when I try and create foreign keys

I am relatively new to mysql and writing queries. I am trying to create a database that has multiple different relationships. I am able to create the tables and assign unique indexes, but when I try and alter each table, I get the same error depending on what Foreign Key I am trying to create. Here is the error I am getting:
Error Code: 1072. Key column 'gameID' doesn't exist in table
This is when I try and call
ALTER TABLE `tbl_player` ADD FOREIGN KEY (`gameID`) REFERENCES tbl_game(`gameID`);
Below Is the current SQL script:
drop database if exists test_DB;
create database test_DB;
use test_DB;
drop procedure if exists createdb;
delimiter //
create procedure createdb()
begin
/*Leaderboard*/
drop table if exists tbl_leaderboard;
CREATE TABLE `tbl_leaderboard` (
`leaderboardID` INTEGER NOT NULL,
`totalScore` INTEGER DEFAULT 0 NOT NULL,
`gamesPlayed` INTEGER DEFAULT 0 NOT NULL,
`averageScore` INTEGER DEFAULT 0 NOT NULL,
CONSTRAINT SYS_PK_10503 PRIMARY KEY (`leaderboardID`)
);
/*User ===================================================================================*/
drop table if exists tbl_user;
CREATE TABLE `tbl_user` (
`userID` INTEGER NOT NULL,
`username` VARCHAR(255) NOT NULL,
`user_password` VARCHAR(20) NOT NULL,
`user_email` VARCHAR(20) NOT NULL,
`user_loginAttermpts` INTEGER DEFAULT 0 NOT NULL,
`user_accountStatus` INTEGER DEFAULT 0 NOT NULL,
`user_isAdmin` BOOLEAN NOT NULL,
CONSTRAINT SYS_PK_10513 PRIMARY KEY (`userID`,`username`)
);
/*Player ===================================================================================*/
drop table if exists tbl_player;
CREATE TABLE `tbl_player` (
`player_score` SMALLINT DEFAULT 0 NOT NULL,
`playerID` SMALLINT NOT NULL,
`colour` VARCHAR(20) NOT NULL,
CONSTRAINT SYS_PK_10375 PRIMARY KEY (`player_score`,`playerID`)
);
/*Inventory ===================================================================================*/
drop table if exists tbl_inventory;
CREATE TABLE `tbl_inventory` (
`inventoryID` INTEGER NOT NULL,
`quantity` INTEGER DEFAULT 0 NOT NULL,
CONSTRAINT SYS_PK_10520 PRIMARY KEY (`inventoryID`)
);
/*Tile ===================================================================================*/
drop table if exists tbl_tile;
CREATE TABLE `tbl_tile` (
`tileID` INTEGER NOT NULL,
CONSTRAINT SYS_PK_10547 PRIMARY KEY (`tileID`)
);
/*Board ===================================================================================*/
drop table if exists tbl_board;
CREATE TABLE `tbl_board` (
`boardID` INTEGER NOT NULL,
CONSTRAINT SYS_PK_10538 PRIMARY KEY (`boardID`)
);
/*Game ===================================================================================*/
drop table if exists tbl_game;
CREATE TABLE `tbl_game` (
`gameID` INTEGER NOT NULL,
`gameNumber` INTEGER DEFAULT 0 NOT NULL,
`numberOfPlayers` INTEGER DEFAULT 0 NOT NULL,
`gameMode` VARCHAR(30) NOT NULL,
CONSTRAINT SYS_PK_10543 PRIMARY KEY (`gameID`)
);
/*Chat ===================================================================================*/
drop table if exists tbl_gameChat;
CREATE TABLE `tbl_gameChat` (
`chatID` SMALLINT NOT NULL,
`text` VARCHAR(255),
CONSTRAINT SYS_PK_10555 PRIMARY KEY (`chatID`)
);
/*TileAsset ===================================================================================*/
drop table if exists tbl_assetTile;
CREATE TABLE `tbl_assetTile` (
`assetTileID` INTEGER NOT NULL,
CONSTRAINT SYS_PK_10545 PRIMARY KEY (`assetTileID`)
);
/*Asset ===================================================================================*/
drop table if exists tbl_asset;
CREATE TABLE `tbl_asset` (
`assetID` INTEGER NOT NULL,
`asset_name` VARCHAR(50) NOT NULL,
`asset_type` VARCHAR(50) NOT NULL,
`asset_value` INTEGER DEFAULT 0 NOT NULL,
CONSTRAINT SYS_PK_10557 PRIMARY KEY (`assetID`)
);
/*Create UNIQUE Indexes*/
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10503_10504 ON `tbl_leaderboard` (`leaderboardID`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10497_10498 ON `tbl_user` (`userID`,`username`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10513_10514 ON `tbl_user` (`userID`,`username`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10375_10376 ON `tbl_player` (`player_score`,`playerID`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10520_10521 ON `tbl_inventory` (`inventoryID`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10547_10548 ON `tbl_tile` (`tileID`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10538_10539 ON `tbl_board` (`boardID`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10543_10544 ON `tbl_game` (`gameID`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10555_10556 ON `tbl_gameChat` (`chatID`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10545_10546 ON `tbl_assetTile` (`assetTileID`);
CREATE UNIQUE INDEX SYS_IDX_SYS_PK_10557_10558 ON `tbl_asset` (`assetID`);
/*Add Foreign Keys*/
ALTER TABLE `tbl_player` ADD FOREIGN KEY (`gameID`) REFERENCES tbl_game(`gameID`);
ALTER TABLE `tbl_player` ADD FOREIGN KEY (`tileID`) REFERENCES tbl_tile(`tileID`);
ALTER TABLE `tbl_player` ADD FOREIGN KEY (`userID`) REFERENCES tbl_user(`userID`);
ALTER TABLE `tbl_inventory` ADD FOREIGN KEY (`playerID`) REFERENCES tbl_player(`playerID`);
ALTER TABLE `tbl_inventory` ADD FOREIGN KEY (`assetID`) REFERENCES tbl_asset(`assetID`);
ALTER TABLE `tbl_tile` ADD FOREIGN KEY (`boardID`) REFERENCES tbl_board(`boardID`);
ALTER TABLE `tbl_board` ADD FOREIGN KEY (`gameID`) REFERENCES tbl_game(`gameID`);
ALTER TABLE `tbl_gameChat` ADD FOREIGN KEY (`gameID`) REFERENCES tbl_game(`gameID`);
ALTER TABLE `tbl_assetTile` ADD FOREIGN KEY (`tileID`) REFERENCES tbl_tile(`tileID`);
ALTER TABLE `tbl_assetTile` ADD FOREIGN KEY (`assetID`) REFERENCES tbl_asset(`assetID`);
ALTER TABLE `tbl_leaderboard` ADD FOREIGN KEY (`player_score`) REFERENCES tbl_player(`player_score`);
ALTER TABLE `tbl_leaderboard` ADD FOREIGN KEY (`userID`) REFERENCES tbl_user(`userID`);
ALTER TABLE `tbl_leaderboard` ADD FOREIGN KEY (`username`) REFERENCES tbl_user(`username`);
end //
delimiter ;
call createdb();
Any suggestions on how to fix this issue would be greatly appreciated and possible improvements to the fomrmat.
Your table tbl_player doesn't have a column gameID add it in you create script to add the FOREIGN KEY, the same applies to all foreign keys you are trying to add. the column must be available in the table where you are willing to create the FOREIGN KEY
CREATE TABLE `tbl_player` (
`player_score` SMALLINT DEFAULT 0 NOT NULL,
`playerID` SMALLINT NOT NULL,
`colour` VARCHAR(20) NOT NULL,
`gameID` INTEGER,
CONSTRAINT SYS_PK_10375 PRIMARY KEY (`player_score`,`playerID`)
);
Before creating foreign keys for any table, make sure the table contains/has the column you are adding foreign key constraint to.
In your case if you see the table tbl_player (as you have shared)
/*Player ===================================================================================*/
drop table if exists tbl_player;
CREATE TABLE `tbl_player` (
`player_score` SMALLINT DEFAULT 0 NOT NULL,
`playerID` SMALLINT NOT NULL,
`colour` VARCHAR(20) NOT NULL,
CONSTRAINT SYS_PK_10375 PRIMARY KEY (`player_score`,`playerID`)
);
does not have column gameID and the query you are running ALTER TABLE `tbl_player` ADD FOREIGN KEY (`gameID`) REFERENCES tbl_game(`gameID`); is trying to add Foreign key constraint on column gameID (which does not exists in the tbl_player table) thereby resulting into an error you mentioned Error Code: 1072. Key column 'gameID' doesn't exist in table
To solve this you can :
Alter table to add a new column and then add foreign key constraint to that column :
ALTER TABLE tbl_player
ADD COLUMN gameID INT,
ADD FOREIGN KEY fk_name(gameID) REFERENCES tbl_game(gameID) ON DELETE CASCADE;
Add a column gameID while creating the table as below :
/*Player ===================================================================================*/
drop table if exists tbl_player;
CREATE TABLE `tbl_player` (
`player_score` SMALLINT DEFAULT 0 NOT NULL,
`playerID` SMALLINT NOT NULL,
`colour` VARCHAR(20) NOT NULL,
`gameID` INTEGER NOT NULL,
CONSTRAINT SYS_PK_10375 PRIMARY KEY (`player_score`,`playerID`)
);
then alter the table to create column gameID as foreign key :
ALTER TABLE tbl_player add FOREIGN KEY(gameID) REFERENCES tbl_game(gameID);
Any one of the above points should work.
Cheers!!

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;

Confusing cannot add foreign key constraint error

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`)
);

Foreign Key Unexpected

I'm using MySQL workbench and I am trying to create a table consist of foreign key using SQL Query. I am having problem with the Foreign part.
create table employee_position
(
ePID int primary key,
ePName varchar(45) not null,
eID int foreign key references employee_profile(eID)
)
Your syntax is wrong. Try:
create table employee_position
(
ePID int primary key,
ePName varchar(45) not null,
eID int,
foreign key (keyname) references employee_profile(eID)
)
For more information see the mysql documentation
create table employee_position
(
ePID int primary key,
ePName varchar(45) not null,
eID int,
foreign key (eID) references employee_profile(eID)
)
SQLFiddle demo
Check FOREIGN KEYS in MySQL.
Try this:
CREATE TABLE employee_position
(
ePID INT NOT NULL AUTO_INCREMENT,
ePName VARCHAR(45) NOT NULL,
eID INT NOT NULL,
PRIMARY KEY (ePID),
KEY CustomerID (eID),
CONSTRAINT FK_employee_position_EP
FOREIGN KEY (eID)
REFERENCES employee_profile (eID) ON DELETE CASCADE ON UPDATE CASCADE
);

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.