MySQL - Foreign key on delete set null in not null field - mysql

This is probably a trivial question, but I'm still a little clumsy when it comes to foreign key constraints so I wanted to make sure.
Let's say I have a table countries with the fields country_id (PK) and name, and a table cities with the fields city_id (PK), name and country_id (FK).
The foreign key cities.country_id has the constraint ON DELETE SET NULL. As I understand it, this means that if a record from countries is deleted, any records in cities that reference that deleted record's country_id will have its country_id field set to NULL.
What if, however, cities.country_id has the attribute NOT NULL? Will this prevent the foreign key constraint from working properly? It would make sense that it does, but I just want to check.

If you set ON DELETE SET NULL to your foreign key then it won't allow you to set the field as NOT NULL.
So you won't be able to create or alter the table with column as NOT NULL and ON DELETE SET NULL on CountryId
When I run the below statements:
CREATE TABLE `country` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ;
CREATE TABLE `city` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`countryId` int(10) unsigned DEFAULT NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_country` (`countryId`),
CONSTRAINT `FK_country` FOREIGN KEY (`countryId`) REFERENCES `country` (`id`) ON DELETE SET NULL ON UPDATE SET NULL
);
And I got the error in MySQL 5.5 is:
Schema Creation Failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_country` (`countryId`),
CONSTRAINT `' at line 4:

Related

MySQL: Cannot add or update a child row: a foreign key constraint fails when referencing UID

I have 2 tables : tbl_usr_info which has a UID which is a primary key and auto-increment and tbl_login_info which has a LoginID (primary) and the UID along with some other information like timestamps etc.
I'm trying to reference UID from tbl_login_info with UID in tbl_usr_info by running this sql statement
CONSTRAINT `uid-info/login` FOREIGN KEY (`UID`) REFERENCES `tbl_usr_info` (`UID`)
but I'm getting this error:
Cannot add or update a child row: a foreign key constraint fails (CONSTRAINT uid-info/login FOREIGN KEY (UID) REFERENCES tbl_usr_info (UID))
tbl_usr_info table
CREATE TABLE `tbl_usr_info` (
`UID` int(50) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL DEFAULT '',
`password` varchar(50) NOT NULL DEFAULT '',
`email` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`UID`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
tbl_usr_login table
CREATE TABLE `tbl_usr_login` (
`LoginID` int(11) NOT NULL AUTO_INCREMENT,
`UID` int(50) NOT NULL,
`ip_address` varchar(55) DEFAULT NULL,
`device` varchar(100) DEFAULT NULL,
`time_stamp` datetime DEFAULT NULL,
PRIMARY KEY (`LoginID`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
Is it the order in which I'm referencing it that's wrong?
I tested your foreign key constraint and it works without error for me. But my tables were empty.
One of the most common types of failures for a foreign key constraint is that when you create the constraint, the child table contains some values that are not present in the parent table. The foreign key constraint cannot be satisfied in that case, so creation of the constraint fails.
You can check for unmatched UID values:
SELECT COUNT(*)
FROM tbl_usr_login AS l
LEFT OUTER JOIN tbl_usr_info AS i
ON l.UID = i.UID
WHERE i.UID is NULL;
P.S.: This is tangential to your question, but I notice you're using INT(50). The argument to INT doesn't mean what you think it means. INT(50) does NOT mean you can store 50 digits. See my answer to Types in MySQL: BigInt(20) vs Int(20)
To enable foreign key, child and parent column definitions must match along with some other conditions.
In your problem case, following steps should resolve it:
create user table.
create login info table.
add index/key on the UID column in login table.
now, add referential constraint on it.
Refer to:
Mysql: Using foreign key constraints:
https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html

Cannot add foreign key constraint - MySQL ERROR 1215 (HY000)

I am trying to create database for gym management system, but I can't figure out why I am getting this error. I've tried to search for the answer here, but I couldn't find it.
ERROR 1215 (HY000): Cannot add foreign key constraint
CREATE TABLE sales(
saleId int(100) NOT NULL AUTO_INCREMENT,
accountNo int(100) NOT NULL,
payName VARCHAR(100) NOT NULL,
nextPayment DATE,
supplementName VARCHAR(250),
qty int(11),
workoutName VARCHAR(100),
sDate datetime NOT NULL DEFAULT NOW(),
totalAmount DECIMAL(11,2) NOT NULL,
CONSTRAINT PRIMARY KEY(saleId, accountNo, payName),
CONSTRAINT FOREIGN KEY(accountNo) REFERENCES accounts(accountNo) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY(payName) REFERENCES paymentFor(payName) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY(supplementName) REFERENCES supplements(supplementName) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY(workoutName) REFERENCES workouts(workoutName) ON DELETE CASCADE ON UPDATE CASCADE
);
ALTER TABLE sales AUTO_INCREMENT = 2001;
Here is the parent tables.
CREATE TABLE accounts(
accountNo int(100) NOT NULL AUTO_INCREMENT,
accountType VARCHAR(100) NOT NULL,
firstName VARCHAR(50) NOT NULL,
lastName VARCHAR(60) NOT NULL,
birthdate DATE NOT NULL,
gender VARCHAR(7),
city VARCHAR(50) NOT NULL,
street VARCHAR(50),
cellPhone VARCHAR(10),
emergencyPhone VARCHAR(10),
email VARCHAR(150) NOT NULL,
description VARCHAR(350),
occupation VARCHAR(50),
createdOn datetime NOT NULL DEFAULT NOW(),
CONSTRAINT PRIMARY KEY(accountNo)
);
ALTER TABLE accounts AUTO_INCREMENT = 1001;
CREATE TABLE supplements(
supplementId int(100) NOT NULL AUTO_INCREMENT,
supplementName VARCHAR(250) NOT NULL,
manufacture VARCHAR(100),
description VARCHAR(150),
qtyOnHand INT(5),
unitPrice DECIMAL(11,2),
manufactureDate DATE,
expirationDate DATE,
CONSTRAINT PRIMARY KEY(supplementId, supplementName)
);
ALTER TABLE supplements AUTO_INCREMENT = 3001;
CREATE TABLE workouts(
workoutId int(100) NOT NULL AUTO_INCREMENT,
workoutName VARCHAR(100) NOT NULL,
description VARCHAR(7500) NOT NULL,
duration VARCHAR(30),
CONSTRAINT PRIMARY KEY(workoutId, workoutName)
);
ALTER TABLE workouts AUTO_INCREMENT = 4001;
CREATE TABLE paymentFor(
payId int(100) NOT NULL AUTO_INCREMENT,
payName VARCHAR(100) NOT NULL,
amount DECIMAL(11,2),
CONSTRAINT PRIMARY KEY(payId, payName)
);
ALTER TABLE paymentFor AUTO_INCREMENT = 5001;
Can you guys help me with this problem? Thanks.
If you ever want to find out, why that error was , all you have to do is run below command and look for "LATEST FOREIGN KEY ERROR"
Command to run :-
mysql> SHOW ENGINE INNODB STATUS
You will know the reason for your such errors.
For a field to be defined as a foreign key, the referenced parent field must have an index defined on it.
As per documentation on foreign key constraints:
REFERENCES parent_tbl_name (index_col_name,...)
Define an INDEX on workouts.workoutName, paymentFor.paymentName, and supplements.supplementName respectively. And make sure that child column definitions must match with those of their parent column definitions.
Change workouts table definition as below:
CREATE TABLE workouts(
workoutId int(100) NOT NULL AUTO_INCREMENT,
workoutName VARCHAR(100) NOT NULL,
description VARCHAR(7500) NOT NULL,
duration VARCHAR(30),
KEY ( workoutName ), -- <---- this is newly added index key
CONSTRAINT PRIMARY KEY(workoutId, workoutName)
);
Change supplements table definition as below:
CREATE TABLE supplements(
supplementId int(100) NOT NULL AUTO_INCREMENT,
supplementName VARCHAR(250) NOT NULL,
manufacture VARCHAR(100),
description VARCHAR(150),
qtyOnHand INT(5),
unitPrice DECIMAL(11,2),
manufactureDate DATE,
expirationDate DATE,
KEY ( supplementName ), -- <---- this is newly added index key
CONSTRAINT PRIMARY KEY(supplementId, supplementName)
);
Change paymentFor table definition as below:
CREATE TABLE paymentFor(
payId int(100) NOT NULL AUTO_INCREMENT,
payName VARCHAR(100) NOT NULL,
amount DECIMAL(11,2),
KEY ( payName ), -- <---- this is newly added index key
CONSTRAINT PRIMARY KEY(payId, payName)
);
Now, change child table definition as below:
CREATE TABLE sales(
saleId int(100) NOT NULL AUTO_INCREMENT,
accountNo int(100) NOT NULL,
payName VARCHAR(100) NOT NULL,
nextPayment DATE,
supplementName VARCHAR(250) NOT NULL,
qty int(11),
workoutName VARCHAR(100) NOT NULL,
sDate datetime NOT NULL DEFAULT NOW(),
totalAmount DECIMAL(11,2) NOT NULL,
CONSTRAINT PRIMARY KEY(saleId, accountNo, payName),
CONSTRAINT FOREIGN KEY(accountNo)
REFERENCES accounts(accountNo)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY(payName)
REFERENCES paymentFor(payName)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY(supplementName)
REFERENCES supplements(supplementName)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY(workoutName)
REFERENCES workouts(workoutName)
ON DELETE CASCADE 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
Foreign Keys are a way of implementing relationships/constraints between columns in different tables.
There are different categories of constraints that influence how they’re enforced when a row is updated or deleted from the parent table:
◾Cascade: If a row is deleted from the parent then any rows in the child table with a matching FK value will also be deleted. Similarly for changes to the value in the parent table.
◾Restrict: A row cannot be deleted from the parent table if this would break a FK constraint with the child table. Similarly for changes to the value in the parent table.
◾No Action: Very similar to “Restrict” except that any events/triggers on the parent table will be executed before the constraint is enforced – giving the application writer the option to resolve any FK constraint conflicts using a stored procedure.
◾Set NULL: If NULL is a permitted value for the FK column in the child table then it will be set to NULL if the associated data in the parent table is updated or deleted.
◾Set Default: If there is a default value for the FK column in the child table then it will be used if the associated data in the parent table is updated or deleted. Note that this is not implemented in this version – the constraint can be added to the schema but any subsequent deletion or update to the column in the parent table will fail.
Some times you will get this error "#1215 - Cannot add foreign key constraint" because of table TYPE (InnoDB, MyISAM,..) mismatch.
So change your table type into same and try applying for foreign key constraint
mysql> ALTER TABLE table_name ENGINE=InnoDB;
mysql> ALTER TABLE Orders
ADD FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
This might work for some people. Simply add the default character set as utf8
DEFAULT CHARACTER SET = utf8;
I was getting the same error. The reason was I was referring to a column in a table created with charset utf8 from a table created using charset latin.
The tables created using mySQL workbench create table utility have default charset latin.
Easy approach to find this out if you are using workbench is to view the table create statement of any table. You will have the default charset string at the end.
I'm not answering the above question but just for people who will run into the same mysql error.
All I did was to change the referenced table engine to innodb.
I encounter this error I add foreign key constraint for a column that has 'not null constraint' but I specified the 'on delete set null' in the foreign constraint. This is a contradiction that it may not be obvious at first.
Here are my two tables:
CREATE TABLE study (
id int(11) NOT NULL AUTO_INCREMENT primary key,
name varchar(100) NOT NULL,
introduction text,
objective varchar(250) DEFAULT NULL,
method text,
result text,
conclusion varchar(250) DEFAULT NULL,
future_action varchar(100) DEFAULT NULL
);
drop table client_study;
CREATE TABLE client_study (
id int(11) NOT NULL AUTO_INCREMENT primary key,
client_id int(11),
study_id int(11) not null, --If delete 'not null' error goes away!
contact_person int(11),
effective_date datetime DEFAULT CURRENT_TIMESTAMP,
trial_site int(11) DEFAULT NULL,
UNIQUE KEY unqidx_client_study (client_id,study_id)
);
ALTER TABLE client_study
ADD CONSTRAINT FOREIGN KEY (study_id) REFERENCES study(id)
ON DELETE SET NULL ON UPDATE CASCADE;
ERROR 1215 (HY000): Cannot add foreign key constraint
If you remove the NOT NULL constraint on the study_id column in the client_study table, the foreign key can be added. The other alternative is to keep the not null constraint on the client_table, but modify the foreign key definition to on delete no action or other choices.

SQL #1215 - Cannot add foreign key constraint

I've got this code to create an SQL table, however I'm facing a #1215 error.
CREATE TABLE ‘Categorie’ (
‘catID’ int(11) NOT NULL AUTO_INCREMENT,
‘naam’ varchar(20) NOT NULL,
‘prioriteit’ int(2) NOT NULL,
‘subCatVan’ int(11) DEFAULT NULL,
PRIMARY KEY (‘catID’),
CONSTRAINT ‘subCatVan’ FOREIGN KEY (‘subCatVan’) REFERENCES Categorie
(‘catID’) ON DELETE SET NULL ON UPDATE CASCADE
);
Help is appreciated!
As Jens already pointed out, there is an issue with your ticks. First, the identifier quote character in MySQL is the backtick (`) by default, second, you are not using ticks for the table name in your foreign key constraint.
Replace all ticks with backticks and your statement will work (even without ticks around the table name in the foreign key constraint). Leave all ticks out and your statement will work. Change REFERENCES Categorie to REFERENCES ‘Categorie’ and your statement will work (although probably not as expected).
I would recommend using backticks in all places as a good practice:
CREATE TABLE `Categorie` (
`catID` int(11) NOT NULL AUTO_INCREMENT,
`naam` varchar(20) NOT NULL,
`prioriteit` int(2) NOT NULL,
`subCatVan` int(11) DEFAULT NULL,
PRIMARY KEY (`catID`),
CONSTRAINT `subCatVan` FOREIGN KEY (`subCatVan`) REFERENCES `Categorie`
(`catID`) ON DELETE SET NULL ON UPDATE CASCADE
);
What currently happens is that you are actually not creating a table named Categorie, but instead a table named ‘Categorie’ (including the ticks). Because you are not using the same ticks in your foreign key constraint, MySQL looks for a table named Categorie without the ticks and thus cannot find the target for your reference.
try this
CREATE TABLE `Categorie` (
`catID` INT(11) NOT NULL AUTO_INCREMENT,
`naam` VARCHAR(20) NOT NULL,
`prioriteit` INT(2) NOT NULL,
`subCatVan` INT(11) DEFAULT NULL,
PRIMARY KEY (`catID`),
CONSTRAINT `subCatVan` FOREIGN KEY (`subCatVan`) REFERENCES Categorie
(`catID`) ON DELETE SET NULL ON UPDATE CASCADE
);

Why setting the key constraints on column removes "NOT NULL" from it (MySQL)?

I have the code to create a table:
DROP TABLE IF EXISTS `database`.`creatures_kinds` ;
CREATE TABLE IF NOT EXISTS `database`.`creatures_kinds` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`parent_id` INT UNSIGNED NULL,
`name_en` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`, `parent_id`),
INDEX `parent_id` (`parent_id` ASC),
CONSTRAINT `parent`
FOREIGN KEY (`parent_id`)
REFERENCES `database`.`creatures_kinds` (`id`)
ON DELETE RESTRICT
ON UPDATE CASCADE)
ENGINE = InnoDB;
What surprise me is that the newly created table looks like this:
Why the parent_id is set to NOT NULL when I wrote NULL in the CREATE TABLE?
Does it has something to do with the PRIMARY KEY or FOREIGN KEY?
I guess that parent_id is an identifiable relation (it points to more general creature kind, e.g. from pigeon to bird, and it's NULL for top-level creature kinds).
A PRIMARY KEY is a unique index where all key columns must be defined as NOT NULL. If they are not explicitly declared as NOT NULL, MySQL declares them so implicitly (and silently). MySQL Manual

MySQL Adding Foreign Key

I have two tables:
Table 1: staff_incharge with following columns - First_name and staff_id (This is the Primary Key)
Table 2: student-info with following columns - First_name Last_name ID(Primary Key)
I have another column staff_id which I'm trying to make as a Foreign key, but it shows some error.
This is the query I'm using in MySQL Query Browser:
alter table `student_info`
add constraint foreign key (staff_id)
references staff_incharge(staff_id);
The error is:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'student_info add constraint foreign key (staff_id) references
staff_incharge' at line 1.
Can someone tell me what I'm doing wrong?
student_info table was created first and then staff_incharge was created next.
Output of the following query:
SHOW CREATE TABLE student_info;
CREATE TABLE `student_info` (
`First_name` varchar(15) NOT NULL DEFAULT '',
`Last_name` varchar(45) NOT NULL,
`ID` int(10) unsigned NOT NULL DEFAULT '0',
`staff_id` int(11) NOT NULL DEFAULT '0',
`City` varchar(15) NOT NULL DEFAULT '',
`Marks1` int(10) unsigned NOT NULL DEFAULT '0',
`Marks2` int(10) unsigned NOT NULL DEFAULT '0',
`Marks3` int(10) unsigned NOT NULL DEFAULT '0',
`Total_marks` int(10) unsigned NOT NULL DEFAULT '0',
`Branch` varchar(10) NOT NULL,
PRIMARY KEY (`ID`,`First_name`)
SHOW CREATE TABLE staff_incharge;
'staff_incharge', 'CREATE TABLE `staff_incharge` (
`First_name` varchar(20) NOT NULL,
`Staff_id` int(11) NOT NULL,
PRIMARY KEY (`Staff_id`)
)
Minimum code - without explicitly naming the foreign key constraint (MySQL will choose a semi-random name):
ALTER TABLE student_info
ADD FOREIGN KEY (staff_id)
REFERENCES staff_incharge (staff_id) ;
Naming the foreign key constraint:
ALTER TABLE student_info
ADD CONSTRAINT staff_incharge__student_info__FK -- name of your choice
FOREIGN KEY (staff_id)
REFERENCES staff_incharge (staff_id) ;
I got it! The problem was that I had given different default values for ID and staff_id.
The main thing is to ensure foreign key and referenced column should have same data types, length, attributes, default values, collation.
These links helped:
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
http://forums.mysql.com/read.php?22,19755,499517