sql cannot add foreign key constraint - mysql

i am trying to create a table that uses a foreign key from another table an i keep getting the error:"1215 cannot add foreign key constraint "
i checked and it says the following:
"Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition."
below is my sql code:
show engine innodb status;
CREATE TABLE trainee (
traineeid bigint unsigned NOT NULL,
fname VARCHAR(20),
lname VARCHAR(20),
id INT(9),age INT,
PRIMARY KEY (traineeid));
CREATE TABLE trainer(
trainerid bigint unsigned NOT NULL,
fname VARCHAR(20),lname VARCHAR(20),
id INT(9),
PRIMARY KEY (trainerid));
CREATE TABLE club(
clubid bigint unsigned NOT NULL,
clubname VARCHAR(20),
PRIMARY KEY(clubid));
CREATE TABLE team(
teamid bigint unsigned NOT NULL,
teamname VARCHAR(20),
clubid bigint unsigned,
INDEX(clubid),
FOREIGN KEY (clubid) REFERENCES club (clubid)
ON DELETE SET NULL
ON UPDATE CASCADE,
PRIMARY KEY(teamid));
CREATE TABLE competition(
competitionid bigint unsigned NOT NULL,
competitiondate DATE,
competitionname VARCHAR(40),
PRIMARY KEY(competitionid));
CREATE TABLE trainertoteam(
trainerid bigint unsigned not null,
teamid bigint unsigned not null,
PRIMARY KEY(teamid,trainerid),
INDEX(trainerid),
FOREIGN KEY (trainerid) REFERENCES trainer (trainerid)
ON DELETE set null
ON UPDATE CASCADE,
INDEX(teamid),
FOREIGN KEY (teamid) REFERENCES team (teamid)
ON DELETE CASCADE
ON UPDATE CASCADE);
could you help me to find what is the error?
i know the error is when creating trainertoteam table

Related

Failed to add the foreign key constraint in MySQL: error 3780

I am getting the error:
Error Code: 3780. Referencing column 'category' and referenced column 'category_id' in foreign key constraint 'product_ibfk_1' are incompatible.
drop table if exists Provider;
drop table if exists Category;
drop table if exists Product;
create table Provider
(
privider_id serial not null primary key,
login_password varchar(20) not null
constraint passrule3 check(login_password sounds like '[A-Za-z0-9]{6,20}'),
fathersname varchar(20) not null,
name_of_contact_face varchar(10) not null,
surname varchar(15),
e_mail varchar(25) unique
constraint emailrule2 check(e_mail sounds like '[A-Za-z0-9]{10,10})\#gmail.com\s?')
);
create table Category
(
title varchar(20),
category_id serial not null primary key
);
create table Product
(
barecode serial not null primary key,
provider_id bigint not null,
manufacturer varchar(25) not null,
category_id bigint not null,
dimensions varchar(10) not null,
amount int not null,
date_of_registration datetime not null,
#constraint 'provider_for_product'
foreign key (provider_id) references Provider (provider_id) on delete restrict on update cascade,
foreign key (category_id) references Category (category_id) on delete restrict on update cascade
);
The datatypes of the two columns referenced in a foreign key constraint need to match
In MySQL, SERIAL is an alias for BIGINT UNSIGNED AUTO_INCREMENT.
To make a foreign key that references this column, it must be BIGINT UNSIGNED, not a signed BIGINT.
You might like to view a checklist of foreign key mistakes I contributed to: https://stackoverflow.com/a/4673775/20860
I also cover foreign key mistakes in more detail in a chapter of my book, SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.

Can not Add External Index Constraints

This is the exact error that WAMP returns when I run the child code from an external file called entries.txt
ERROR 1215 (HY000): Can not Add External Index Constraints
I need to be able to connect the parent tables to the child table so that links can be made between the tables easily.
The question states:
Create and populate a third table called entries, again using query scripts.
This table should contain foreign keys to allow sensible links to be
made with the other two tables, together with the dates of each exam.
Parent Tables:
CREATE TABLE IF NOT EXISTS students(
student_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
first_name VARCHAR(20) NOT NULL,
middle_name VARCHAR(20),
last_name VARCHAR(40) NOT NULL,
email VARCHAR(60) NOT NULL,
password CHAR(40) NOT NULL,
reg_date DATETIME NOT NULL,
PRIMARY KEY (student_id),
UNIQUE (email));
CREATE TABLE IF NOT EXISTS subjects(
subject_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
subject_name CHAR(30) NOT NULL,
level_of_entry VARCHAR(10) NOT NULL,
exam_board CHAR(20) NOT NULL,
PRIMARY KEY (subject_id));
Child Table:
CREATE TABLE IF NOT EXISTS entries(
date_of_exam DATETIME NOT NULL,
first_name VARCHAR,
middle_name VARCHAR,
last_name VARCHAR,
subject_name CHAR,
level_of_entry VARCHAR,
exam_board CHAR,
INDEX idx_first_name(first_name),
INDEX idx_middle_name(middle_name),
INDEX idx_last_name(last_name),
INDEX idx_subject_name(subject_name),
INDEX idx_level_of_entry(level_of_entry),
INDEX idx_exam_board(exam_board),
PRIMARY KEY (date_of_exam),
CONSTRAINT fk_first_name FOREIGN KEY (first_name) REFERENCES students(first_name),
CONSTRAINT fk_middle_name FOREIGN KEY (middle_name) REFERENCES students(middle_name),
CONSTRAINT fk_last_name FOREIGN KEY (last_name) REFERENCES students(last_name),
CONSTRAINT fk_subject_name FOREIGN KEY (subject_name) REFERENCES subjects(subject_name),
CONSTRAINT fk_level_of_entry FOREIGN KEY (level_of_entry) REFERENCES subjects(level_of_entry),
CONSTRAINT fk_exam_board FOREIGN KEY (exam_board) REFERENCES subjects(exam_board)
)ENGINE=InnoDB;
A foreign key in the child table must reference the primary key of the parent table only. You don't need to create clones of every attribute column of the parent tables, just the primary key column. If you need to read the other attributes, you'd write a query with a JOIN.
CREATE TABLE IF NOT EXISTS entries(
student_id INT UNSIGNED NOT NULL,
subject_id INT UNSIGNED NOT NULL,
date_of_exam DATETIME NOT NULL,
PRIMARY KEY (student_id, subject_id, date_of_exam),
CONSTRAINT fk_student FOREIGN KEY (student_id) REFERENCES students(student_id),
CONSTRAINT fk_subject FOREIGN KEY (subject_id) REFERENCES subjects(subject_id),
)ENGINE=InnoDB;

Not able to create table with foreign key constraints for two columns?

I have created below airports table :
CREATE TABLE airports(
airport_id int(4) unsigned AUTO_INCREMENT NOT NULL,
airport_name varchar(250),
primary key(airport_id)
)ENGINE=InnoDB;
But when I'm creating schedule table with foreign key constraints,Its not able to create. Below is the script :
CREATE TABLE schedule (
flight_id int(3) unsigned AUTO_INCREMENT NOT NULL,
origin_airport_id int(4),
destination_airport_id int(4) ,
departure_time char(15) not null,
arrival_time char(15) not null,
duration varchar(20) not null,
flight_fare decimal(9,2) not null,
PRIMARY KEY (flight_id),
FOREIGN KEY(origin_airport_id,destination_airport_id) REFERENCES airports(airport_id,airport_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
Below is the error message from show 'engine innodb status;', when I try to create the schedule table.
Error in foreign key constraint of table airport_db/schedule:
FOREIGN KEY(origin_airport_id,destination_airport_id) REFERENCES airports(airport_id,airport_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB:
Cannot find an index in the referenced table where the referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign- key-constraints.html for correct foreign key definition.
Foreign keys need to reference the primary (or unique) keys of a table. There are no duplicates. And, the types have to exactly match (int doesn't match int unsigned).
So, try this instead:
CREATE TABLE schedule (
flight_id int(3) unsigned AUTO_INCREMENT NOT NULL,
origin_airport_id int(4) unsigned,
destination_airport_id int(4) unsigned,
departure_time char(15) not null,
arrival_time char(15) not null,
duration varchar(20) not null,
flight_fare decimal(9,2) not null,
PRIMARY KEY (flight_id),
FOREIGN KEY(origin_airport_id) REFERENCES airports(airport_id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(destination_airport_id) REFERENCES airports(airport_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
Here is a SQL Fiddle.

changing data type from bigint to tinyint form existing table with foreign key reference

I have to optimize my database which has 212 tables. One table primary key is acting as foreign key for 94 tables. For example I have this table:
create table CUSTOMER (
CUSTOMER_ID BIGINT NOT NULL,
CUSTOMER_NAME VARCHAR(255) NOT NULL UNIQUE,
CONTACT_PERSON VARCHAR(255) NOT NULL,
CUSTOMER_EMAIL VARCHAR(255) NOT NULL,
ADDRESS VARCHAR(255),
CITY VARCHAR(255),
PHONE VARCHAR(255),
FAX VARCHAR(255),
constraint CUSTOMER_PK PRIMARY KEY (CUSTOMER_ID)
);
Here CUSTOMER_ID is acting as a reference that is a foreign key for 94 tables. Here is one table as an example:
create table CUSTOMER_STATUS (
CUSTOMER_DETAILS_ID BIGINT NOT NULL,
CUSTOMER_ID BIGINT NOT NULL,
USER_ID BIGINT NOT NULL,
TRIAL_PERIOD BIGINT NOT NULL,
TRIAL_PERIOD_TYPE BIGINT NOT NULL,
EXPIRY_DATE BIGINT NOT NULL,
MAXIMUM_CLIENTS BIGINT NOT NULL,
STATUS BIGINT NOT NULL,
AUTO_AUTHORIZATION BIGINT NOT NULL,
constraint CUSTOMER_STATUS_PK PRIMARY KEY (CUSTOMER_ID,CUSTOMER_DETAILS_ID),
constraint CUSTOMER_STATUS_FK1 FOREIGN KEY (CUSTOMER_ID) references CUSTOMER(CUSTOMER_ID)
);
I need to change CUSTOMER_ID data type from BIGINT to TINYINT for all tables, but I'm getting an error because of foreign key constraints.
Error:
mysql> alter table CUSTOMER MODIFY CUSTOMER_ID TINYINT;
ERROR 1025 (HY000): Error on rename of '.\uds7\#sql-670_cdd' to '.\uds7\customer' (errno: 150)
What should I do to make changes without affecting my table data?
You can't do that directly.
The things you will do
drop all contraints (foreign key) that references the CUSTOMER table primary key
you can now change the data type of the primary key
change also the data types of the foreign key same with the data type to which the key will be referenced
add foreign key constraints again.
You can disable foreign key constraint checks whilst you make schema changes:
SET foreign_key_checks = 0;
ALTER TABLE CUSTOMER MODIFY CUSTOMER_ID TINYINT;
ALTER TABLE CUSTOMER_STATUS MODIFY CUSTOMER_ID TINYINT;
SET foreign_key_checks = 1;
Note that the data type (including size and sign in the case of integers) of both the referencing and referenced columns must be the same when you reenable foreign key checks.

Can't figure out what's wrong with foreign key constraint statement

This is the error message from show engine innodb status; when I try to create the table:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
110628 16:56:07 Error in foreign key constraint of table test/menu_items:
foreign key(id_menu)
references menus(id)
on update cascade
on delete cascade,
foreign key(id_item)
references items(id)
on update cascade
on delete cascade,
primary key(id_menu, id_item)
) engine=InnoDB:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
These are the relevant SQL statements:
create table if not exists menus (
id mediumint unsigned not null auto_increment,
id_restaurant mediumint unsigned not null,
name varchar(50) not null,
description varchar(255) default null,
foreign key(id_restaurant)
references restaurants(id)
on update cascade
on delete cascade,
primary key(id)
) engine=InnoDB;
create table if not exists items (
id mediumint unsigned not null auto_increment,
id_restaurant mediumint unsigned not null,
name varchar(50),
description text,
type enum('appetizer','salad','soup','entree','dessert','drink','other'),
price decimal(4,2),
foreign key(id_restaurant)
references restaurants(id)
on update cascade
on delete cascade,
primary key(id)
) engine=InnoDB;
create table if not exists order_items (
id_order bigint unsigned not null,
id_item mediumint unsigned not null,
item_name varchar(50),
item_description text,
item_price decimal(4,2),
notes varchar(1024),
quantity smallint unsigned,
foreign key(id_order)
references orders(id)
on update cascade
on delete cascade,
foreign key(id_item)
references items(id)
on update cascade
on delete cascade,
primary key(id_order, id_item)
) engine=InnoDB;
Removing menu_items.id_menu and corresponding foreign key / primary key allows the SQL statements to be parsed properly.
Why can't I make a foreign key reference to menus(id) from menu_items?
You've got a mismatch of datatypes:
create table order_items (
id_order bigint unsigned not null, -- BIGINT
create table items (
id mediumint unsigned not null auto_increment, -- MEDIUMINT
but order_items.id_order references items.id, so they should be the same.
Try changing order_items id_order to medium int:
order_items (
id_order mediumint unsigned not null,