MySql composite foreign key ON DELETE set null [duplicate] - mysql

This question already has an answer here:
Multiple Column Foreign Key: Set single column to Null "ON DELETE" instead of all
(1 answer)
Closed 2 years ago.
Please refer to this SQLFiddle
CREATE TABLE `parent` (
`id` varchar(64) NOT NULL,
`master_id` varchar(64) NOT NULL,
`c1_id` varchar(64) DEFAULT NULL,
`c2_id` varchar(64) DEFAULT NULL,
PRIMARY KEY (`master_id`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `child_1` (
`id` varchar(64) NOT NULL,
`master_id` varchar(64) NOT NULL,
PRIMARY KEY (`master_id`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `child_2` (
`id` varchar(64) NOT NULL,
`master_id` varchar(64) NOT NULL,
PRIMARY KEY (`master_id`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO child_1 (`id`, `master_id`)
VALUES
(1, 'm1');
INSERT INTO child_2 (`id`, `master_id`)
VALUES
(2, 'm2'),
(3, 'm1');
INSERT INTO parent (`id`, `master_id`, `c1_id`, `c2_id`)
VALUES
(4, 'm1', null, null),
(5, 'm1', 1, null),
(6, 'm2', null, 2);
I have multiple tables that have composite Primary Key.
All PK are PRIMARY KEY (master_id, id)
And now I try to add Foreign Keys to these tables.
ALTER TABLE `parent`
ADD CONSTRAINT parent_fk_1
FOREIGN KEY (`master_id`, `c1_id`)
REFERENCES child_1 (`master_id`, `id`)
ON UPDATE CASCADE
ON DELETE SET NULL;
But it throws error Cannot add foreign key constraint.
Here parent.master_id always must stay NOT NULL while c1_id and c2_id can be set to NULL.
Is it possible to achieve this kind of Foreign Key setup?
I found that there is MATCH SIMPLE option that allows composite key to be partial NULL, but how to apply it for ON DELETE SET NULL?

Both referring Column are NOT NULL, so you can't use ON DELETE SET NULL, this violates the NOT NULL
ALTER TABLE `parent`
ADD CONSTRAINT parent_fk_1
FOREIGN KEY (`master_id`, `c1_id`)
REFERENCES child_1 (`master_id`, `id`)
ON UPDATE CASCADE;

Related

cant add or update child row, foreign key fails

This is my sql file:
DROP DATABASE IF EXISTS `dbstudents`;
CREATE DATABASE IF NOT EXISTS `dbstudents`;
USE `dbstudents`;
DROP TABLE IF EXISTS `student_detail`;
CREATE TABLE `student_detail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fav_programming_language` varchar(128) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) DEFAULT NULL,
`last_name` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`student_detail_id` int(11) DEFAULT NULL,
`password` varchar(50) NOT NULL,
`enabled` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_DETAIL_idx` (`student_detail_id`),
CONSTRAINT `FK_DETAIL` FOREIGN KEY (`student_detail_id`) REFERENCES `student_detail` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`authority` varchar(50) NOT NULL,
UNIQUE KEY `authorities_idx_1` (`id`,`authority`),
CONSTRAINT `authorities_ibfk_1` FOREIGN KEY (`id`) REFERENCES `student` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
This is insert statement:
INSERT INTO `student`
VALUES
(1, 'Stefan', 'Stefanovic', 'stefan#gmail.com', 1, 'stefan123', 1),
(2, 'Marko', 'Markovic', 'marko#gmail.com', 1, 'marko123', 1),
(3, 'Jovan', 'Jovanovic', 'jovan#gmail.com', 1, 'jovan123', 1);
This is error:
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`dbstudents`.`student`, CONSTRAINT `FK_DETAIL` FOREIGN KEY (`student_detail_id`) REFERENCES `student_detail` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
I found some solutions but all of them are on some way different then mine. How to solve this? An error occurs when I try to fill in every table except the autorities
As you haven't any student_details already in the system use NULL instead a number and add the number later
INSERT INTO `student`
VALUES
(1, 'Stefan', 'Stefanovic', 'stefan#gmail.com', NULL, 'stefan123', 1),
(2, 'Marko', 'Markovic', 'marko#gmail.com', NULL, 'marko123', 1),
(3, 'Jovan', 'Jovanovic', 'jovan#gmail.com', NULL, 'jovan123', 1);
see example https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=c1bbdd8ee9b9a9af244da774cdb41175

Cannot insert into table with stored generated primary key

I cannot insert data in table with generated stored primary key.
My table is:
CREATE TABLE `living_complex` (
`id` bigint(32) GENERATED ALWAYS AS (`location_id`) STORED NOT NULL,
`location_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unq_living_complex_name` (`name`),
KEY `idx_living_complex_location_id` (`location_id`),
KEY `idx_living_complex_name` (`name`),
CONSTRAINT `fk_living_complex_location_id` FOREIGN KEY (`location_id`) REFERENCES `location` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
My insert statement:
INSERT INTO `reeve`.`living_complex` (`location_id`, `name`)
VALUES ('1', 'some_living_complex');
Error is:
1048: Column 'id' cannot be null
I don't have NOT NULL key-word in create statement. Why does it asks for id?
Got it. There was an mistake in trigger
CREATE DEFINER=`root`#`localhost` TRIGGER `reeve`.`trg_living_complex_object_id` BEFORE INSERT ON `living_complex` FOR EACH ROW
BEGIN
INSERT INTO `reeve`.`object` (
`id`,
`object_type_id`
)
VALUES (
new.id,
(SELECT `object_type`.`id` FROM `reeve`.`object_type` WHERE `table_name` = 'living_complex')
);
END
Which should be AFTER insert. Because I don't have NEW.id (generated by expression) until I do insert.

#1062 - Duplicate entry '19' for key 'PRIMARY'

I have the following table in MySQL version 5.5.24
CREATE TABLE IF NOT EXISTS `bookings` (
`booking_id` int(11) NOT NULL ,
`class_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1;
INSERT INTO `bookings` (`booking_id`, `class_id`, `user_id`) VALUES
(19, 3, 5),
(21, 6, 5);
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) NOT NULL,
`username` varchar(20) NOT NULL,
`firstname` varchar(20) NOT NULL,
`lastname` varchar(20) NOT NULL,
`email` varchar(30) NOT NULL,
`password` varchar(255) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
INSERT INTO `users` (`user_id`, `username`, `firstname`, `lastname`, `email`, `password`) VALUES
(4, 'another', 'Anne', 'Other', 'another#gmail.com', '1234'),
(5, 'rbirney', 'Rosanne', 'Birney', 'rosanne.birney#gmail.com', '1111');
ALTER TABLE `bookings`
ADD PRIMARY KEY (`booking_id`), ADD KEY `class_id` (`class_id`,`user_id`), ADD KEY `user_id` (`user_id`);
ALTER TABLE `classes`
ADD PRIMARY KEY (`class_id`);
ALTER TABLE `users`
ADD PRIMARY KEY (`user_id`);
ALTER TABLE `bookings`
MODIFY `booking_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=22;
ALTER TABLE `classes`
MODIFY `class_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=11;
ALTER TABLE `users`
MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=6;
ALTER TABLE `bookings`
ADD CONSTRAINT `fkBookingClass` FOREIGN KEY (`class_id`) REFERENCES `classes` (`class_id`),
ADD CONSTRAINT `fkBookingUser` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`);
I am getting the following message
#1062 - Duplicate entry '19' for key 'PRIMARY'
anyone have any ideas?
In SQL it is not allowed to use the same value for a primary key twice. (value = 19)
Primary keys are always unique.

Why is my insert statement failing?

I am trying to add to my database table, but seem to get an error. I get a 1452 Error. Here is what I think is the problem: I think my parent_fk is referring to an id what does not yet exist. At least that is what I understand of the following error:
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (assetgallery.ag_asset, CONSTRAINT fk_ag_asset_2 FOREIGN KEY (parent_fk) REFERENCES ag_asset (id) ON DELETE CASCADE ON UPDATE CASCADE)
Say I have a tuple in my database with the id 2. The first tuple:
'2', '8', NULL, NULL, '2', '2015-09-24 09:42:31', 'sabernLogo_0.png', NULL, NULL, NULL, '180', '80', NULL, '1', NULL, NULL, '3', '1'
I am trying to add another with an INSERT statement. I am Inserting without an id, so it looks like this :
Insert into ag_asset
(album_fk, parent_fk, head_fk, status_fk, modified, filename, title, `desc`, `text`, width, height, owner_fk, locked, remarks, group_fk, user_fk, type_fk)
VALUES(6, 0, null, 1, '2015-10-15 15:47:13.0', 'index.png', null, null, null, 215, 234, null, null, null, null, 3, 1);
From what I understand because my id is Autoincrement'ed, not filling this in would result in a freshly made id, being 2.
Here is the create statement
CREATE TABLE `ag_asset` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`album_fk` int(10) DEFAULT NULL,
`parent_fk` int(10) DEFAULT NULL,
`head_fk` int(10) DEFAULT NULL,
`status_fk` int(10) DEFAULT '1',
`modified` datetime NOT NULL,
`filename` varchar(255) DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
`desc` text,
`text` longtext,
`width` int(10) DEFAULT NULL,
`height` int(10) DEFAULT NULL,
`owner_fk` int(10) DEFAULT NULL,
`locked` int(10) DEFAULT NULL,
`remarks` text,
`group_fk` int(10) DEFAULT NULL,
`user_fk` int(10) DEFAULT NULL,
`type_fk` int(10) DEFAULT '1',
PRIMARY KEY (`id`),
KEY `in_filename` (`filename`(12)),
KEY `in_title` (`title`(12)),
KEY `fk_ag_asset_1` (`album_fk`),
KEY `fk_ag_asset_2` (`parent_fk`),
KEY `fk_ag_asset_3` (`head_fk`),
KEY `fk_ag_asset_4` (`status_fk`),
KEY `fk_ag_asset_5` (`owner_fk`),
KEY `fk_ag_asset_6` (`type_fk`),
CONSTRAINT `fk_ag_asset_1` FOREIGN KEY (`album_fk`) REFERENCES `ag_album` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_ag_asset_2` FOREIGN KEY (`parent_fk`) REFERENCES `ag_asset` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_ag_asset_3` FOREIGN KEY (`head_fk`) REFERENCES `ag_asset` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_ag_asset_4` FOREIGN KEY (`status_fk`) REFERENCES `ag_status` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_ag_asset_5` FOREIGN KEY (`owner_fk`) REFERENCES `ag_owner` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_ag_asset_6` FOREIGN KEY (`type_fk`) REFERENCES `ag_type` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;
Do I understand the error correctly or am I even looking in the wrong direction?
In foreign key concept whatever value you are trying to insert/update in child table, must exist in its parent/referenced table.
Here you are trying to insert values like 0, NULL etc in columns for those you have created referenced and your master table does not keep these values.
Solution1:
Either first add these values in master table then you can insert in child table.
Solution2:
If you want to add such data in child table forcefully as per your requirement which is not suggested then you can do as-
set foreign_key_checks=0;
Insert statement here...
set foreign_key_checks=1;

#1451 - Cannot delete or update a parent row: a foreign key constraint fails

My code SQL is :
enter code here
CREATE TABLE IF NOT EXISTS `participer` (
`statut_Invitation` tinyint(1) NOT NULL,
`NumVersion` int(11) NOT NULL,
`InviteCode` varchar(255) NOT NULL,
`IdQuest` int(11) NOT NULL,
PRIMARY KEY (`NumVersion`,`InviteCode`,`IdQuest`),
KEY `FK_Participer_NumVersion` (`NumVersion`),
KEY `FK_Participer_IdQuest` (`IdQuest`),
KEY `FK_Participer_InviteCode` (`InviteCode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `participer` (`statut_Invitation`, `NumVersion`, `InviteCode`, `IdQuest`) VALUES
(0, 2, '2548', 1),
(0, 2, '8742', 1);
CREATE TABLE IF NOT EXISTS `questionnaire` (
`IdQuest` int(11) NOT NULL AUTO_INCREMENT,
`Nom` varchar(256) DEFAULT NULL,
`DateCreation` date DEFAULT NULL
PRIMARY KEY (`IdQuest`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
INSERT INTO `questionnaire` (`IdQuest`, `Nom`, `DateCreation`, `ID`) VALUES
(1, 'Parions Sport', '2015-03-23'),
(2, 'GPS', '2015-03-23');
CREATE TABLE IF NOT EXISTS `utilisateurs` (
`InviteCode` varchar(255) NOT NULL,
`Email` varchar(25) NOT NULL,
`DateNaissance` date DEFAULT NULL,
`Ville` varchar(25) DEFAULT NULL,
PRIMARY KEY (`InviteCode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `utilisateurs` (`InviteCode`, `Email`, `DateNaissance`, `Ville`) VALUES
('1235314', 'bocchi#gmail.com', NULL, NULL),
('2548', 'bocchiTEST#gmail.com', NULL, NULL),
('337752493652424404824466004444846460026', 'dylan#gmail.com', NULL, NULL),
('53131172170670664482420846024208824402', 'dylan2#gmail.com', NULL, NULL),
('5446544', 'lool', NULL, NULL),
('8742', 'max#gmail.com', NULL, NULL);
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `versionquestionnaire` (
`NumVersion` int(11) NOT NULL,
`DateExpiration` date DEFAULT NULL,
`SommeNote` float DEFAULT NULL,
`NbReponses` int(11) DEFAULT NULL,
`IdQuest` int(11) NOT NULL,
PRIMARY KEY (`NumVersion`,`IdQuest`),
KEY `FK_VersionQuestionnaire_IdQuest` (`IdQuest`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `versionquestionnaire` (`NumVersion`, `DateExpiration`, `SommeNote`, `NbReponses`, `IdQuest`) VALUES
(1, '2015-03-26', 120, 2, 1),
(1, '2015-03-30', 100, 1, 2),
(2, '2015-03-26', 210, 3, 1),
(2, '2015-03-30', 300, 4, 2);
ALTER TABLE `participer`
ADD CONSTRAINT `FK_Participer_IdQuest` FOREIGN KEY (`IdQuest`) REFERENCES `versionquestionnaire` (`IdQuest`),
ADD CONSTRAINT `FK_Participer_InviteCode` FOREIGN KEY (`InviteCode`) REFERENCES `utilisateurs` (`InviteCode`),
ADD CONSTRAINT `FK_Participer_NumVersion` FOREIGN KEY (`NumVersion`) REFERENCES `versionquestionnaire` (`NumVersion`);
ALTER TABLE `versionquestionnaire`
ADD CONSTRAINT `FK_VersionQuestionnaire_IdQuest` FOREIGN KEY (`IdQuest`) REFERENCES `questionnaire` (`IdQuest`);
When i want to delete the version 1 of the questionnaire 1 :
DELETE FROM `versionquestionnaire` WHERE `versionquestionnaire`.`NumVersion` = 1 AND `versionquestionnaire`.`IdQuest` = 1;
I have a error :
1451 - Cannot delete or update a parent row: a foreign key constraint fails (`testbug`.`participer`, CONSTRAINT `FK_Participer_IdQuest` FOREIGN KEY (`IdQuest`) REFERENCES `versionquestionnaire` (`IdQuest`)) ;
I don't understand because in the table participer, there isn't the couple with NumVersion = 1 and IdQuest = 1, there are 2 couples with NumVersion = 1 and IdQuest = 1. So my request may be run.
In short, you can't delete records from versionquestionnaire because some records in participer table reference records in participer.
Your request clearly violates IdQuest constraint: you're trying to delete a record with IdQuest = 1, while BOTH participants that still reference that ID.