Foreign key constraint fails in transaction - php

I'm developing a web-based application with PHP/MySQL + Yii Framework. The problem occurs as a constraint check error in a transaction.
I have the following tables:
User
CREATE TABLE IF NOT EXISTS `User` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) DEFAULT NULL,
`surname` varchar(64) DEFAULT NULL,
`email` varchar(128) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`creation_date` datetime DEFAULT NULL,
`last_login_date` datetime DEFAULT NULL,
`status` tinyint(1) DEFAULT '0',
`level` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=40 ;
CandidateInfo
CREATE TABLE IF NOT EXISTS `CandidateInfo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`candidate_status_id` int(11) DEFAULT NULL,
`name` varchar(64) DEFAULT NULL,
`surname` varchar(64) DEFAULT NULL,
`email` varchar(128) DEFAULT NULL,
`gender` tinyint(1) DEFAULT '0',
`date_of_birth` datetime DEFAULT NULL,
`home_phone` varchar(20) DEFAULT NULL,
`mobile_phone` varchar(20) DEFAULT NULL,
`creation_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`rating` tinyint(1) DEFAULT '0',
`location` varchar(100)DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_candidateinfo_user` (`id`),
KEY `FK_candidateinfo_candidatestatus` (`candidate_status_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=26 ;
Basically I'm trying to add a new row to User table, and then use the insert id to add a new row to the CandidateInfo table (user_id column)
The php code is as
$transaction = Yii::app()->db->beginTransaction();
try {
$user->save();
$candidate->setAttribute('user_id', $user->id);
$candidate->save();
$transaction->commit();
} catch (Exception $e) {
$transaction->rollBack();
var_dump($e->getMessage());
}
The error is:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`origo`.`CandidateInfo`, CONSTRAINT `FK_candidateinfo_user` FOREIGN KEY (`id`) REFERENCES `User` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION). The SQL statement executed was: INSERT INTO `CandidateInfo` (`gender`, `rating`, `name`, `surname`, `email`, `date_of_birth`, `home_phone`, `mobile_phone`, `user_id`) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6, :yp7, :yp8)
When i check the mysql query logs, i see that it takes the right user_id for the INSERT statement for CandidateInfo table. But fails with the above error. From my understanding, it is supposed to work, but may be i am mistaken and this is not the way transactions are meant to work.
Both tables are InnoDB.
Thanks in advance.
Edit:
Sorry forgot to paste the FK relations.
ALTER TABLE `CandidateInfo`
ADD CONSTRAINT `FK_candidateinfo_candidatestatus` FOREIGN KEY (`candidate_status_id`) REFERENCES `CandidateStatus` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_candidateinfo_user` FOREIGN KEY (`id`) REFERENCES `User` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;

ALTER TABLE `CandidateInfo`
ADD CONSTRAINT `FK_candidateinfo_candidatestatus` FOREIGN KEY (`candidate_status_id`) REFERENCES `CandidateStatus` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_candidateinfo_user` FOREIGN KEY (`id`) REFERENCES `User` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
should be
ALTER TABLE `CandidateInfo`
ADD CONSTRAINT `FK_candidateinfo_candidatestatus` FOREIGN KEY (`candidate_status_id`) REFERENCES `CandidateStatus` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `FK_candidateinfo_user` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
you've got id references id in yours.

Your error stack:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (origo.CandidateInfo, CONSTRAINT FK_candidateinfo_user FOREIGN KEY (id) REFERENCES User (id) ON DELETE NO ACTION ON UPDATE NO ACTION).
The SQL statement executed was:
INSERT INTO `CandidateInfo`
( `gender`, `rating`, `name`, `surname`, `email`,
`date_of_birth`, `home_phone`, `mobile_phone`, `user_id`
)
VALUES ( :yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6, :yp7, :yp8 )
Your CandidateInfo table defines id field as auto_increment primary key field and a foreign key as well.
And your insert statement does not include id, read from its parent user table.
And hence on insert a new id value is generated for candidateinfo table and applied.
Which intern failed as it did not match any of the primary key id value of the parent user table.
And hence is the error.
Note:
In a child table if your are referring a pk field of a master as a foreign key field,
you should not apply auto_increment for it but just refer.
And looking closely the candidateinfo structure, I feel that you might want to map use_id to user.id field. Making that change, with proper foreign key definition used, would resolve your problem.

Related

A foreign key constraint fails on production but not on localhost

I have a simple CRUD that i built and it works perfectly on localhost, but for some reason it keeps on insisting throwing errors when on production.
Posts table is -
CREATE TABLE `posts` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`title` json NOT NULL,
`meta_title` json NOT NULL,
`meta_description` json NOT NULL,
`slug` json NOT NULL,
`body` json DEFAULT NULL,
`published_at` date DEFAULT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT '0',
`author_id` bigint unsigned DEFAULT NULL,
`category_id` bigint unsigned DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `posts_author_id_foreign` (`author_id`),
KEY `posts_category_id_foreign` (`category_id`),
CONSTRAINT `posts_author_id_foreign` FOREIGN KEY (`author_id`) REFERENCES `Authors` (`id`) ON DELETE CASCADE,
CONSTRAINT `posts_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `Categories` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=115 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Authors table is -
CREATE TABLE `authors` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` json NOT NULL,
`description` json DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
And the error that im getting while trying to create a new post (once again, only in production env) is -
[2021-09-29 07:13:44] production.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`blog`.`posts`, CONSTRAINT `posts_author_id_foreign` FOREIGN KEY (`author_id`) REFERENCES `Authors` (`id`) ON DELETE CASCADE) (SQL: insert into `posts` (`title`, `meta_title`, `meta_description`, `slug`, `body`, `published_at`, `enabled`, `author_id`, `category_id`, `updated_at`, `created_at`) values ({"en":"test","es":"test"}, {"en":"test","es":"test"}, {"en":"test","es":"test"}, {"en":"testtt","es":"test"}, {"en":"<p>asd<\/p>","es":"<p>dsdas<\/p>"}, ?, 0, 8, 5, 2021-09-29 07:13:44, 2021-09-29 07:13:44)) {"userId":1,"exception":"[object] (Illuminate\\Database\\QueryException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`blog`.`posts`, CONSTRAINT `posts_author_id_foreign` FOREIGN KEY (`author_id`) REFERENCES `Authors` (`id`) ON DELETE CASCADE) (SQL: insert into `posts` (`title`, `meta_title`, `meta_description`, `slug`, `body`, `published_at`, `enabled`, `author_id`, `category_id`, `updated_at`, `created_at`) values ({\"en\":\"test\",\"es\":\"test\"}, {\"en\":\"test\",\"es\":\"test\"}, {\"en\":\"test\",\"es\":\"test\"}, {\"en\":\"testtt\",\"es\":\"test\"}, {\"en\":\"<p>asd<\\/p>\",\"es\":\"<p>dsdas<\\/p>\"}, ?, 0, 8, 5, 2021-09-29 07:13:44, 2021-09-29 07:13:44)) at /var/www/html/blog/vendor/laravel/framework/src/Illuminate/Database/Connection.php:692)
Different versions of MySQL, at a guess. In both of your constraints you reference the table name with a capital letter.
CONSTRAINT `posts_author_id_foreign` FOREIGN KEY (`author_id`) REFERENCES `Authors` (`id`) ON DELETE CASCADE,
CONSTRAINT `posts_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `Categories` (`id`) ON DELETE CASCADE
MySQL 8.0 can deal with that, MySQL5.7 can not (going by tests on my own localhost and production setups).

Error while inserting the recordsCannot add or update a child row: a foreign key constraint fails

I have created tables in MYSQL as follows
Author Table
CREATE TABLE `author` (
`AuthorId` varchar(25) NOT NULL,
`AuthorName` varchar(50) NOT NULL,
PRIMARY KEY (`AuthorId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Books Table
CREATE TABLE `books` (
`DocId` int(11) NOT NULL,
`ISBN` varchar(13) NOT NULL,
PRIMARY KEY (`DocId`),
KEY `DocId` (`DocId`),
CONSTRAINT `books_ibfk_1` FOREIGN KEY (`DocId`) REFERENCES `document`
(`DocId`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Document Table
CREATE TABLE `document` (
`DocId` int(11) NOT NULL,
`Title` varchar(50) NOT NULL,
`PublishDate` date DEFAULT NULL,
`AuthorId` varchar(10) DEFAULT NULL,
`DocType` varchar(10) DEFAULT NULL,
PRIMARY KEY (`DocId`),
KEY `AuthorId` (`AuthorId`),
CONSTRAINT `document_ibfk_3` FOREIGN KEY (`AuthorId`) REFERENCES `author`
(`AuthorId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
I made a server for my PHP website on XAMPP and am using mysql but when I try inserting the values in Document table I get
error while inserting the recordsCannot add or update a child row: a foreign
key constraint fails (`librarydb`.`document`, CONSTRAINT `document_ibfk_3`
FOREIGN KEY (`AuthorId`) REFERENCES `author` (`AuthorId`))
How do I resolve this issue?
Your linked fields author.AuthorId and document.AuthorId are not defined the same way.
From the docs:
Corresponding columns in the foreign key and the referenced key must
have similar data types. The size and sign of integer types must be
the same. The length of string types need not be the same.
So make them both varchar(10) NOT NULL - or whatever you need.

One to many relationship in SQL - foreign key error

I am trying to create a campus structure. So buildings have floors, floors have rooms. I am trying to create a relational database such that multiple rooms relate to one floor and multiple floors relate to their building.
Here is my structure for the building and floor tables:
CREATE TABLE `building` (
`id` int(11) NOT NULL,
`name` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE `floor` (
`id` int(11) NOT NULL,
`building_id` int(11) DEFAULT NULL,
`level` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `floor_building_id__fk` (`building_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
I want to insert more than one floor in the floor table relating to the same building_id using:
INSERT INTO `floor` SET id=3, `number` = 420, building_id=(SELECT id FROM building WHERE id=2);
However I keep getting the following error:
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`seatspace`.`floor`, CONSTRAINT `building_id` FOREIGN KEY (`id`) REFERENCES `building` (`id`))
I want to insert, update and delete floors relating to their specified building_id. Any help would be appreciated.
I have fixed the problem by changing the constraint name for the foreign key. I also rewrote parts of the schema so all of the desired columns were present. Here is the final schema and CRUD.
CREATE TABLE `floor` (
`floor_id` int(11) NOT NULL AUTO_INCREMENT,
`number` int(11) NOT NULL,
`building_id` int(11) NOT NULL,
PRIMARY KEY (`floor_id`),
UNIQUE KEY `floor_id_UNIQUE` (`floor_id`),
KEY `building_id_idx` (`building_id`),
CONSTRAINT `building_id` FOREIGN KEY (`building_id`) REFERENCES `building`
(`building_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
INSERT INTO `floor` (floor_id, `number`, building_id) VALUES (default, 3,
(SELECT building_id FROM building WHERE building_id=2)) ;
UPDATE `floor` SET `number`=3, building_id=1 WHERE floor_id=2;
DELETE FROM `floor` WHERE floor_id=3;
CREATE TABLE `building` (
`building_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`building_id`),
UNIQUE KEY `building_id_UNIQUE` (`building_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
INSERT INTO building (building_id, name) VALUES (DEFAULT, '1 West');
UPDATE `building` SET `name`='3 West' WHERE building_id=2;
DELETE FROM `building` WHERE building_id=2;

cannot add or update a child row a foreign key constraint fails mysql Error Number: 1452

the berita_ukm table
CREATE TABLE `berita_ukm` (
`id_berita` int(11) NOT NULL AUTO_INCREMENT,
`id_admin` int(11) DEFAULT NULL,
`judul_berita` varchar(45) DEFAULT NULL,
`content` varchar(225) DEFAULT NULL,
`tanggal` date DEFAULT NULL,
PRIMARY KEY (`id_berita`),
FOREIGN KEY (`id_admin`) REFERENCES `admin` (`id_admin`)
)
admin table
CREATE TABLE `berita_ukm` (
`id_admin` int(11) NOT NULL AUTO_INCREMENT,
`name` int(11) DEFAULT NULL,
PRIMARY KEY (`id_admin`),
)
and i found error like this
Error Number: 1452
Cannot add or update a child row: a foreign key constraint fails
(`tugas_akhir`.`berita_ukm`, CONSTRAINT `berita_ukm_ibfk_1`
FOREIGN KEY (`id_admin`) REFERENCES `admin` (`id_admin`))
INSERT INTO `berita_ukm`
(`id_berita`, `tanggal`, `judul_berita`, `content`)
VALUES ('34', '3/25/2014', 'putri', 'nfdn')
please help me what to do. thank you
I guess you misplaced the col names in your insert("id_berita" in place of "id_admin" ), since col "id_berita" is auto increment, you don't need to provide value for that col during insert.
INSERT INTO `berita_ukm`
(`id_admin`, `tanggal`, `judul_berita`, `content`)
VALUES ('34', '3/25/2014', 'putri', 'nfdn')

Insertion Failed:Cannot add or update a child row: a foreign key constraint fails

I have two tables- users and language with a foreign key link of their primary key 'id'.
I have checked that the type is innoDB for the tables. I have delete- restrict and update -cascade.
This insert query, inserts it into the language table: (it can be more than one row which is added as the form has dynamic clickevent button)
if(empty($_SESSION['user_id'])) { // user not logged in; redirect to somewhere else }
$sql_insert = "INSERT into `language`
(`native`,`other`,`other_list`,`other_read`, `other_spokint`
,`other_spokprod`,`other_writ` )
VALUES
('$native','$other','$other_list','$other_read','$other_spokint','$other_spokprod',
'$other_writ') ";
mysql_query($sql_insert,$link) or die("Insertion Failed:" . mysql_error());
}
This is the full error:
Insertion Failed:Cannot add or update a child row: a foreign key constraint fails
(`members`.`language`, CONSTRAINT `language_ibfk_1` FOREIGN KEY (`id`)
REFERENCES `users` (`id`))
Any help would be appreciated!
Table structure for table language:
CREATE TABLE IF NOT EXISTS `language` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`native` varchar(30) NOT NULL,
`other` varchar(30) NOT NULL,
`other_list` varchar(9) NOT NULL,
`other_read` varchar(9) NOT NULL,
`other_spokint` varchar(9) NOT NULL,
`other_spokprod` varchar(9) NOT NULL,
`other_writ` varchar(9) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
RELATIONS FOR TABLE `language`:
`id`
`users` -> `id`
You have to use a structure like this:
create table users (
id int not null auto_increment,
<additional fields>,
primary key (id)
) ENGINE=InnoDB;
create table language(
id int not null auto_increment,
user_id int not null,
<additional fields>,
primary key (id),
foreign key (user_id) references users(id) on delete restrict on update cascade
) ENGINE=InnoDB;

Categories