Foreign Keys and MySQL Errors - mysql

I have the following script to create a table in MySQL version 5.1 which is to refer to 3 other tables. All 3 tables have been created using InnoDB, and all 3 tables have the ID column defined as INT.
I have created other tables successfully which reference ACCOUNT and PERSON, however, this is the first table which references ADDRESS, so I've included the definition for that table, as run, below as well.
The error which I'm getting is ERROR 1005 (HY000) with errno 150, which I understand to be relating to foreign key creation.
The script which fails is (extra columns removed for simplicity):
CREATE TABLE WORK_ORDER (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ACCOUNT_ID INT NOT NULL,
CUSTOMER_ID INT NOT NULL,
SALES_ID INT,
TRADES_ID INT,
LOCATION_ID INT NOT NULL,
INDEX CUST_INDEX(CUSTOMER_ID),
INDEX SALES_INDEX(SALES_ID),
INDEX TRADES_INDEX(TRADES_ID),
INDEX ACCOUNT_INDEX(ACCOUNT_ID),
INDEX LOCATION_INDEX(LOCATION_ID),
FOREIGN KEY (CUSTOMER_ID) REFERENCES PERSON(ID) ON DELETE CASCADE,
FOREIGN KEY (SALES_ID) REFERENCES PERSON(ID) ON DELETE SET NULL,
FOREIGN KEY (TRADES_ID) REFERENCES PERSON(ID) ON DELETE SET NULL,
FOREIGN KEY (ACCOUNT_ID) REFERENCES ACCOUNT(ID) ON DELETE CASCADE,
FOREIGN KEY (LOCATION_ID) REFERENCES ADDRESS(ID) ON DELETE SET NULL
) ENGINE=InnoDB;
The SQL statement used to create the ADDRESS table is below (extra columns removed for simplicity).
CREATE TABLE ADDRESS (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
PERSON_ID INT NOT NULL,
ACCOUNT_ID INT NOT NULL,
ADDRESS_L1 VARCHAR(50),
ADDRESS_L2 VARCHAR(50),
CITY VARCHAR(25),
PROVINCE VARCHAR(20),
POSTAL_CODE VARCHAR(6),
COUNTRY VARCHAR(25),
INDEX CUST_INDEX(PERSON_ID),
INDEX ACCOUNT_INDEX(ACCOUNT_ID),
FOREIGN KEY (ACCOUNT_ID) REFERENCES ACCOUNT(ID) ON DELETE CASCADE,
FOREIGN KEY (PERSON_ID) REFERENCES PERSON(ID) ON DELETE CASCADE
) ENGINE=InnoDB;
I've browsed through several questions here dealing with similar issues, but most seem to be duplicate definitions and non-matching field types, as well as some not using InnoDB for one or the other of the tables. However, none of these seem to be the problem. Any ideas?

You can always issue a 'SHOW ENGINE INNODB STATUS' command. Buried in the output will be a "LATEST FOREIGN KEY ERROR" section, which will have more details on exactly what caused the '150' error:
mysql> create table a (x int not null) type=innodb;
Query OK, 0 rows affected, 1 warning (0.02 sec)
mysql> create table b (y int not null, foreign key (y) references a (x) on delete set null) type=innodb;
ERROR 1005 (HY000): Can't create table './test/b.frm' (errno: 150)
mysql> show engine innodb status;
[..... snip snip snip ...]
------------------------
LATEST FOREIGN KEY ERROR
------------------------
091129 16:32:41 Error in foreign key constraint of table test/b:
foreign key (y) references a (x) on delete set null) type=innodb:
You have defined a SET NULL condition though some of the
columns are defined as NOT NULL.
[.... snip snip snip ...]

Related

Error Code 1215 Cannot Add Foreign Code Constraint

My code:
CREATE TABLE Horse (
ID SMALLINT UNSIGNED AUTO_INCREMENT,
RegisteredName VARCHAR(15),
PRIMARY KEY (ID)
);
CREATE TABLE Student (
ID SMALLINT UNSIGNED AUTO_INCREMENT,
FirstName VARCHAR(20),
LastName VARCHAR(30),
PRIMARY KEY (ID)
);
CREATE TABLE LessonSchedule (
HorseID SMALLINT UNSIGNED NOT NULL,
StudentID SMALLINT UNSIGNED NOT NULL,
LessonDateTime DATETIME NOT NULL,
Primary Key (HorseID, StudentID, LessonDateTime),
Foreign Key (HorseID) REFERENCES Horse(ID)
ON DELETE CASCADE,
Foreign Key (StudentID) REFERENCES Student(ID)
ON DELETE SET NULL
);
I'm trying to create "LessonSchedule" with these requirements:
HorseID - integer with range 0 to 65 thousand, not NULL, partial primary key, foreign key references Horse(ID)
StudentID - integer with range 0 to 65 thousand, foreign key references Student(ID)
LessonDateTime - date/time, not NULL, partial primary key
If a row is deleted from Horse, the rows with the same horse ID should be deleted from LessonSchedule automatically.
If a row is deleted from Student, the same student IDs should be set to NULL in LessonSchedule automatically.
The create horse table and create student table was given to me.
I am getting the error:
Query failed: ERROR 1215 (HY000) at line 15:
Cannot add foreign key constraint
I tested your table creation statements, and then ran SHOW ENGINE INNODB STATUS. This includes a section that gives more specific information about the reason for the failure.
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2021-11-08 10:31:11 0x700002686000 Error in foreign key constraint of table test/lessonschedule:
Foreign Key (StudentID) REFERENCES Student(ID) ON DELETE SET NULL ):
You have defined a SET NULL condition though some of the
columns are defined as NOT NULL.
This means you can't define a foreign key with ON DELETE SET NULL if the column it is based on is defined with the NOT NULL option (as a PRIMARY KEY column must be).

MariaDB - Create many to many relationship table between two entities [duplicate]

This question already has answers here:
MySQL Creating tables with Foreign Keys giving errno: 150
(20 answers)
Closed 3 years ago.
I am having a problem creating a many to many relationship table in MariaDB.
I have tried using the workbench, manual creation scripts and the "Show Create Table xxxxxxx;" from another already created n to n tables but the result is always the same, the following error:
Error Code: 1005. Can't create table `asi_234_api_establecimientos`.`oe_modalidad` (errno: 150 "Foreign key constraint is incorrectly formed")
The code I am using to create the table:
CREATE TABLE `oe_modalidad` (
`oferta_establecimiento_id` bigint(20) NOT NULL,
`modalidad_id` bigint(20) NOT NULL,
KEY `fk_oe_modalidades_oferta_establecimiento1_idx` (`oferta_establecimiento_id`),
KEY `fk_oe_modalidad_modalidad1_idx` (`modalidad_id`),
CONSTRAINT `fk_oe_modalidad_modalidad1` FOREIGN KEY (`modalidad_id`) REFERENCES `modalidad` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_oe_modalidades_oferta_establecimiento1` FOREIGN KEY (`oferta_establecimiento_id`) REFERENCES `oferta_establecimiento` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB
I have tried running this in two different versions of MariaDB, 10.0.38 and 5.5.60 but I keep getting the same error.
This is a very short example:
create table Table1(
id int auto_increment key,
name varchar(50) not null
);
create table Table2(
id int auto_increment key,
name varchar(50) not null
);
create table Table3(
idTable1 int not null,
idTable2 int not null,
primary key(idTable1, idTable2),
CONSTRAINT fk_table3_table1 foreign key (idTable1) references Table1 (id),
CONSTRAINT fk_table3_table2 foreign key (idTable2) references Table2 (id)
);
And remember, Table1 and Table2 primary key have to be same type of Table3 foreign key.

Error Code: 1215. Cannot add foreign key constraint in MySQL

I have an error code which is Error Code: 1215. Cannot add foreign key constraint in MySQL. My code is
DROP TABLE IF EXISTS Formed;
DROP TABLE IF EXISTS Album;
DROP TABLE IF EXISTS Band;
DROP TABLE IF EXISTS Customers;
DROP TABLE IF EXISTS Track;
CREATE TABLE Formed(
FormedID int NOT NULL,
YearFormed int,
CountryFormed varchar(50),
CityFormed varchar(50),
BandMembers varchar(400),
PRIMARY KEY(FormedID))
ENGINE=InnoDB;
CREATE TABLE Track (
TrackID int NOT NULL,
AlbumID int NOT NULL,
Songs varchar (100),
TrackNumber varchar (20),
Title varchar (20),
TrackDuration varchar (4),
PRIMARY KEY (TrackID),
FOREIGN KEY (AlbumID) REFERENCES Album(AlbumID)ON DELETE SET NULL ON UPDATE CASCADE)
ENGINE=InnoDB;
CREATE TABLE Album(
AlbumID int NOT NULL,
TrackID int NOT NULL,
BandID int NOT NULL,
Price varchar(5),
PublicationDate varchar(11),
Title varchar(30),
Genre varchar (36),
PRIMARY KEY(AlbumID),
FOREIGN KEY (TrackID) REFERENCES Track(TrackID)ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (BandID) REFERENCES Band(BandID)ON DELETE SET NULL ON UPDATE CASCADE)
ENGINE=InnoDB;
CREATE TABLE Band(
BandID int NOT NULL,
AlbumID int NOT NULL,
RecordLabel varchar(50),
PRIMARY KEY(BandID),
FOREIGN KEY (AlbumID) REFERENCES Album(AlbumID)ON DELETE SET NULL ON UPDATE CASCADE)
ENGINE=InnoDB;
CREATE TABLE Customers (
CustomerID int NOT NULL,
CName varchar (20),
CPhone int (11),
CEmail varchar (50),
CPPaid varchar (50),
CPDate date,
PRIMARY KEY (CustomerID))
ENGINE=InnoDB;
It creates the first table named Formed, but it's giving me the error when it tries and creates the second table and I don't know why. I know a bit about MySQL and I'm teaching myself about Foreign Keys. I have had a look online on why I could be getting this error but couldn't find anything useful.
From the error message, it seems like you are trying to create Track table before Album table and hence, it's failing as it is not able to find parent table (and column) for foreign key constraint.
I would suggest creating the tables with Primary keys only and then, apply foreign key constraints once all 3 tables are created, e.g.:
ALTER TABLE `Track`
ADD FOREIGN KEY (AlbumID) REFERENCES Album(AlbumID)ON DELETE SET NULL ON UPDATE CASCADE);
As a rule All reference fields in child tables MUST HAVE index defined on them as like in parent table. They must also follow some other constraints.
As per documentation on foreign key constraints:
REFERENCES parent_tbl_name (index_col_name,...)
Define an INDEX on relevant child columns. And make sure that child column definitions must match with those of their parent column definitions.
Code change suggested:
CREATE TABLE Formed( ... ) -- no change suggested
CREATE TABLE Customers ( ... ) -- no change suggested
CREATE TABLE Band(
...
AlbumID int NOT NULL,
...
KEY (AlbumID), -- <---- add this line
...
);
CREATE TABLE Album(
...
TrackID int NOT NULL,
BandID int NOT NULL,
...
KEY (TrakID), -- <---- add this line
KEY (BandID), -- <---- add this line
...
-- FOREIGN KEY (TrackID) -- <-- add this using ALTER
-- REFERENCES Track(TrackID) -- after creating
-- ON DELETE SET NULL ON UPDATE CASCADE, -- Track table
);
ALTER TABLE Band ADD
FOREIGN KEY ( AlbumID )
REFERENCES Album( AlbumID )
ON DELETE SET NULL ON UPDATE CASCADE;
CREATE TABLE Track ( ... ) -- no changes suggested
ALTER TABLE Album ADD
FOREIGN KEY ( TrackID )
REFERENCES Track( TrackID );
ON DELETE SET NULL ON UPDATE CASCADE;
Refer to:
MySQL Using FOREIGN KEY Constraints
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION

How do I make a column not null and be a foreign key in MySQL

I am trying to create a table that is a foreign key of another table and make it not null, but I am running into trouble making both happen. I was able to successfully get foreign keys working that did not require NOT NULL but I can't get both working.
Here is the line giving me trouble
CONSTRAINT instructor FOREIGN KEY (id) REFERENCES Instructor(id) NOT NULL
then I get the error:
CONSTRAINT instructor FOREIGN KEY (id) REFERENCES Instructor(id) NOT NULL,
*
ERROR at line 5:
ORA-00907: missing right parenthesis
Also, I am getting a weird error when trying to create a table (note, this table is created after creating the table that contains the above error) where it fails at a very trivial part:
CREATE TABLE Enrollment (
CONSTRAINT class_id FOREIGN KEY (id) REFERENCES Class(id) NOT NULL,
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id) NOT NULL,
cost int NOT NULL
);
Then for that command I get this error:
CREATE TABLE Enrollment (
*
ERROR at line 1:
ORA-00904: : invalid identifier
How can I fix these two errors?
You need to create the column before you try creating constraints on the column.
You have:
CREATE TABLE Enrollment (
CONSTRAINT class_id FOREIGN KEY (id) REFERENCES Class(id) NOT NULL,
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id) NOT NULL,
cost int NOT NULL
);
You need:
CREATE TABLE Enrollment (
id INT NOT NULL CONSTRAINT class_id REFERENCES Class(id),
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id),
cost INT NOT NULL
);
Note that in the first line, the FOREIGN KEY isn't necessary because the column is implied. In the second line, the id is identified. You could also write:
CREATE TABLE Enrollment
(
id INT NOT NULL,
CONSTRAINT class_id FOREIGN KEY (id) REFERENCES Class(id),
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id),
cost INT NOT NULL
);
It is unusual, though not automatically wrong, to make a single column (id) be a foreign key of two tables simultaneously. It isn't clear if you actually want three columns in your table — and if you do, which column names are in your table.
You could also use the appropriate notation for an automatically allocated type in MySQL syntax (SERIAL instead of INT NOT NULL, or add AUTO_INCREMENT, etc).
Maybe you're really after:
CREATE TABLE Enrollment
(
id SERIAL,
class_id INT NOT NULL CONSTRAINT class_id REFERENCES Class(id),
member_id INT NOT NULL CONSTRAINT member_id REFERENCES RecCenterMember(id),
cost INT NOT NULL
);
This makes more sense in general. You're creating a new enrollment record for a pre-existing class, and for a pre-existing recreation centre member, and recording its cost.
Syntax diagrams vs actual behaviour
If, as Michael - sqlbot suggests — and I've no reason whatsoever to disbelieve him — MySQL recognizes but does not respond to the REFERENCES clause in a column definition in a CREATE TABLE statement but only acts on full FOREIGN KEY clauses, then you have to adjust my suggested answers from their syntactically correct but semantically ignored form to something like:
Option 1 (minimally changing the SQL from the question):
CREATE TABLE Enrollment (
id INT NOT NULL,
CONSTRAINT class_id FOREIGN KEY (id) REFERENCES Class(id),
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id),
cost int NOT NULL
);
Option 2 (what I consider the most plausible version):
CREATE TABLE Enrollment
(
id SERIAL,
class_id INT NOT NULL,
CONSTRAINT fk_class_id FOREIGN KEY (class_id) REFERENCES Class(id),
member_id INT NOT NULL,
CONSTRAINT fk_member_id FOREIGN KEY (member_id) REFERENCES RecCenterMember(id),
cost INT NOT NULL
);
Or some other variant of this syntax based on the desired table schema ignoring the FK constraints, then adding the constraints along the lines shown.
Key Point
You must define the columns before you define the foreign keys based on those columns.

Create Foreign Key in Mysql have error Cannot resolve table name close to

I have trouble in adding a foreign key. I have the following script:
CREATE DATABASE IF NOT EXISTS dbdemo;
use dbdemo;
CREATE TABLE categories(
cat_id int unsigned not null auto_increment primary key,
cat_name varchar(255) not null,
cat_description text
) ENGINE=InnoDB;
CREATE TABLE products(
prd_id int unsigned not null auto_increment primary key,
prd_name varchar(355) not null,
prd_price decimal,
cat_id int unsigned not null,
constraint fk_cat
FOREIGN KEY fk_cat( cat_id )
REFERENCES categories( cat_id )
ON UPDATE cascade
ON DELETE RESTRICT
) ENGINE=InnoDB;
CREATE TABLE vendors(
vdr_id int unsigned not null auto_increment primary key,
vdr_name varchar(255)
) ENGINE=InnoDB;
ALTER TABLE products
ADD COLUMN prod_vdr_id int unsigned not null;
Then I got error when I try to add a FOREIGN KEY :
ALTER TABLE products
ADD FOREIGN KEY fk_vendor(prod_vdr_id)
REFERENCES vendor(vdr_id)
ON UPDATE CASCADE
ON DELETE NO ACTION;
Then I got this error:
Error Code: 1005. Can't create table 'dbdemo.#sql-565_35' (errno: 150)
If i run "Show Engine innodb status;" I got :
------------------------
LATEST FOREIGN KEY ERROR
------------------------
150430 15:30:00 Error in foreign key constraint of table dbdemo/#sql-565_35:
FOREIGN KEY fk_vendor(prod_vdr_id)
REFERENCES vendor(vdr_id)
ON UPDATE CASCADE
ON DELETE NO ACTION:
Cannot resolve table name close to:
(vdr_id)
ON UPDATE CASCADE
ON DELETE NO ACTION
Can anyone show me some light where went wrong?
TQVM
It is VENDORS not VENDOR
ALTER TABLE products
ADD FOREIGN KEY fk_vendor(prod_vdr_id)
REFERENCES vendors(vdr_id)
ON UPDATE CASCADE
ON DELETE NO ACTION;