Ok, so I've been trying to figure out why I keep getting this specific error. MySql keeps giving me error code 1452. Cannot add or update a child row. My tables are as such.
CREATE TABLE IF NOT EXISTS `ecommerce`.`departments` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM;
INSERT INTO `ecommerce`.`departments`
VALUES (1, 'Development'), (2, 'Marketing'),
(3, 'Sales'), (4, 'Customer Service');
CREATE TABLE IF NOT EXISTS `ecommerce`.`department_roles` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(100) NOT NULL ,
`map` VARCHAR(255) NOT NULL ,
`parent_id` INT NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM;
INSERT INTO `ecommerce`.`department_roles`
VALUES (1, 'Admin', '/admin', 0), (2, 'Create', '/admin', 1),
(3, 'Update', '/admin', 1), (4, 'Delete', '/admin', 1);
CREATE TABLE IF NOT EXISTS `ecommerce`.`department_roles_map` (
`id` INT NOT NULL AUTO_INCREMENT ,
`department_roles_id` INT NOT NULL ,
`departments_id` INT NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_drm_departments` (`departments_id` ASC) ,
INDEX `fk_drm_department_roles` (`department_roles_id` ASC) ,
CONSTRAINT `fk_drm_departments`
FOREIGN KEY (`departments_id` )
REFERENCES `ecommerce`.`departments` (`id` )
ON DELETE CASCADE
ON UPDATE NO ACTION,
CONSTRAINT `fk_drm_department_roles`
FOREIGN KEY (`department_roles_id` )
REFERENCES `ecommerce`.`department_roles` (`id` )
ON DELETE CASCADE
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Now, when I try to select from departments and department_roles, I show data.
SELECT * FROM department_roles;
+----+--------+--------+-----------+
| id | name | map | parent_id |
+----+--------+--------+-----------+
| 1 | Admin | /admin | 0 |
| 2 | Create | /admin | 1 |
| 3 | Update | /admin | 1 |
| 4 | Delete | /admin | 1 |
+----+--------+--------+-----------+
4 rows in set (0.00 sec)
SELECT * FROM departments;
+----+--------+--------+-----------+
| id | name | map | parent_id |
+----+--------+--------+-----------+
| 1 | Admin | /admin | 0 |
| 2 | Create | /admin | 1 |
| 3 | Update | /admin | 1 |
| 4 | Delete | /admin | 1 |
+----+--------+--------+-----------+
4 rows in set (0.00 sec)
But, when I try to insert into department_roles_map, I get this.
INSERT INTO department_roles_map(department_roles_id, departments_id) VALUES (1, 1);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`ecommerce`.`department_roles_map`, CONSTRAINT `fk_drm_departments` FOREIGN KEY (`departments_id`) REFERENCES `departments` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION)
Any help would be much appreciated!
Firstly, I'm impressed that you managed to create an InnoDB table that has FK references to two MyISAM tables!
Try creating all three table with InnoDB engine and trying again....
Both the parent and the child tables need to use the InnoDB storage engine, but you're using MyISAM for the parent tables.
My guess is that there is already a table named department_roles_map, so when you runCREATE TABLE IF NOT EXISTS it's failing because the table already exists, and ignoring the error. Then when you try to insert data into the other department_roles_map, it fails with the FK error.
But that's just a guess.
I agree with Tom Mac, try creating all 3 tables using InnoDB, but you should also confirm that no other tables with those names already exists.
Related
I have two tables, with foreign keys, but when delete a record from 'fb_campaign' get follow error:
#1451 - Cannot delete or update a parent row: a foreign key constraint fails (mydb.fb_campaign_cat, CONSTRAINT fb_campaign_cat_ibfk_1 FOREIGN KEY (id) REFERENCES fb_campaign (id_cat))
Issue occurs when I add the second foreign key.
table1: fb_campaign_cat
+----+-----------+
| id | fb_cat |
+----+-----------+
| 1 | category1 |
| 2 | category2 |
| 3 | category3 |
+----+-----------+
table2: fb_campaign
+-------+--------+-----------+
| id_fb | id_cat | name |
+-------+--------+-----------+
| 1 | 1 | campaign1 |
| 2 | 2 | campaign2 |
+-------+--------+-----------+
** schema **
CREATE TABLE `fb_campaign_cat` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fb_cat` varchar(30) CHARACTER SET utf8mb4 NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `fb_campaign` (
`id_fb` int(11) NOT NULL AUTO_INCREMENT,
`id_cat` int(11) NOT NULL,
`name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
FOREIGN KEY
ALTER TABLE fb_campaign
ADD CONSTRAINT fb_campaign_cat
FOREIGN KEY (id_cat)
REFERENCES fb_campaign_cat(id)
ON DELETE CASCADE;
ALTER TABLE fb_campaign_cat
ADD FOREIGN KEY (id) REFERENCES fb_campaign(id_cat);
The simple way would be to disable the foreign key check; make the changes then re-enable foreign key check.
SET FOREIGN_KEY_CHECKS=0; -- to disable them
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them
What is the correct statement to make an insert in a table with a self-join?
If I try to make a classic insert I get the error:
Cannot add or update a child row: a foreign key constraint fails
This is my insert query:
insert into mTable(record_name,self_fk,val, note, ref,insert_date, end_date)
values('processo prova',0,1,'nota di prova', 'az12345', NOW(), NOW());
In your INSERT query, you are referencing to a foreign key (the id 0) that doesn't exist -> constraint fails
I saw in your edits, before you roll it back, your CREATE TABLE script.
The field containing the reference to the parent was created this way :
`id_processo_padre` int(11) NOT NULL DEFAULT '1'
I suggest you to edit this field to make it nullable :
ALTER TABLE `mTable` MODIFY `id_processo_padre` int(11) NULL;
This will allow you to INSERT the first top level parent (or any top level parent)
insert into mTable(record_name, self_fk, ...)
values('processo prova', NULL, ...);
-- ^--^----------This
Test it yourself :
Schema (MySQL v5.7)
CREATE TABLE test
(
id INT(6) NOT NULL PRIMARY KEY AUTO_INCREMENT,
parent_id INT(6) NULL,
someData VARCHAR(255),
FOREIGN KEY (parent_id) REFERENCES test(id)
);
INSERT INTO test VALUES (default, null, "parent"),
(default, 1, "child1_1"),
(default, 1, "child1_2"),
(default, 3, "child2_2");
Query #1
SELECT t1.*, t2.someData AS "My parent's name" FROM test t1
LEFT JOIN test t2
ON t2.id = t1.parent_id
ORDER BY t1.id ASC;
Output
| id | parent_id | someData | My parent's name |
| --- | --------- | -------- | ---------------- |
| 1 | null | parent | null |
| 2 | 1 | child1_1 | parent |
| 3 | 1 | child1_2 | parent |
| 4 | 3 | child2_2 | child1_2 |
View on DB Fiddle
I have dug through SO questions and none address my specific issue ... I have read the following relevant threads: Here, to no avail.
I have a simple table with the following data:
|-----------------------------------------------------------------------------|
| id | contractor_id | section_id | page_id | modified | timestamp |
|-----------------------------------------------------------------------------|
Here is the create statement:
CREATE TABLE `reusable_page_modified` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`contractor_id` int(11) DEFAULT NULL,
`section_id` int(11) DEFAULT NULL,
`page_id` int(11) DEFAULT NULL,
`modified` int(1) NOT NULL DEFAULT '1',
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13844 DEFAULT CHARSET=utf8;
Now I have 4 rows in the db right now, and they are (I'll leave off id and timestamp since they are auto generated):
|---------------------------------------------------------|
| contractor_id | section_id | page_id | modified |
###########################################################
| 1016 | 309 | 10303 | 0 |
|----------------------------------------------------------
| 1017 | 309 | 10303 | 1 |
|----------------------------------------------------------
| 1073 | 309 | 10303 | 1 |
|----------------------------------------------------------
| 240 | 309 | 10303 | 1 |
|----------------------------------------------------------
I am focusing on the first line where modified is set to 0. What I want to do is set it to 1 if contractor_id, section_id and page_id all exist. If not, enter a new row.
This is what I have:
INSERT INTO `reusable_page_modified`
(contractor_id, section_id, page_id, modified)
VALUES ('1016', '309', '10303', '1')
ON DUPLICATE KEY UPDATE
`section_id` = '309'
AND `page_id` = '10303'
AND `contractor_id` = '1016';
This creates a new row. I think I am not understanding the ON DUPLICATE KEY UPDATE statment the way it was intended. I have read the MySQL documentation Here and still no help. What am I not seeing here?
You are not far from being correct, but your syntax is a bit off. First, if you want ON DUPLICATE KEY to work when a record with duplicate values for the contractor_id, section_id, and page_id columns is inserted, you will need a unique constraint on these three columns. You can add one using the following:
ALTER TABLE reusable_page_modified
ADD CONSTRAINT u_cnst UNIQUE (contractor_id, section_id, page_id);
Next, for the actual INSERT statement you would use what you have is close, except that you update all the columns which don't require any updating. Instead, leave the three columns alone and instead update the modified column to 1:
INSERT INTO reusable_page_modified
(contractor_id, section_id, page_id, modified)
VALUES ('1016', '309', '10303', '1')
ON DUPLICATE KEY UPDATE
modified = 1
This is my table:
CREATE TABLE `pages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) DEFAULT NULL,
`label` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
where id is a unique id (autoincrement) and parent is also an id from the same table. If parent is NULL, the page hasn't got parent.
What I want? If I delete one parent, it should auto delete all his childs in the same table. I believe that this can be done using on DELETE CASCADE, and this is the way that I want to do it :). But I've tried many configurations of code, and none of them work. Either table cannot be created, or insert query is not working, because of an error that looks similar to "key not exist".
What I found?
How to recursively delete items from table? - answer is great, but with none of code. This answer to the same question:
https://stackoverflow.com/a/9260373/1125465 doesn't work for me. There are some problems with table creation. I think this answer was made in a hurry, and there is some key word missing?
Recursive MySQL Query with relational innoDB this one is simmilar, but not the same case, there are few tables.
Sql server - recursive delete - Come on, there must be a simpliest answer...
Technical info:
mysql Ver 14.14 Distrib 5.1.70, for pc-linux-gnu (x86_64) using
readline 5.1
Table engine: InnoDB
This works for me (and here's a fiddle http://sqlfiddle.com/#!8/d15b4/1):
CREATE TABLE
test
(
id INT NOT NULL PRIMARY KEY,
parent INT,
CONSTRAINT
fk_test_test
FOREIGN KEY
(parent)
REFERENCES
test (id)
ON DELETE CASCADE
);
INSERT
INTO test
VALUES (1, NULL),
(2, 1),
(3, 2),
(4, 3),
(5, NULL),
(6, 5);
SELECT *
FROM test;
+----+--------+
| id | parent |
+----+--------+
| 1 | NULL |
| 5 | NULL |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
| 6 | 5 |
+----+--------+
DELETE
FROM test
WHERE id = 1;
SELECT *
FROM test;
+----+--------+
| id | parent |
+----+--------+
| 5 | NULL |
| 6 | 5 |
+----+--------+
so I have two tables linked by the key 'skillid':
skills
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| skillid | int(11) | NO | PRI | NULL | auto_increment |
| skillname | varchar(30) | NO | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
students_skills
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| ssid | int(11) | NO | PRI | NULL | auto_increment |
| studentid | int(11) | NO | MUL | NULL | |
| skillid | int(11) | NO | MUL | NULL | |
+-----------+---------+------+-----+---------+----------------+
I'm trying to insert multiple rows into the table skills, and then insert these into student_skills based on the ID that was created. I've been looking into using the LAST_INSERT_ID() function:
INSERT INTO skills (skillid , skillname)
VALUES(NULL,'being grateful for help'); # generate ID by inserting NULL
INSERT INTO students_skills (ssid, studentid, skillid)
VALUES(LAST_INSERT_ID(),'1', '2'); # use ID in second table
But I couldn't figure out how to do this for multiple rows at once in one mysql table. I get an error when i simply duplicate the above 4 lines for every row.
ERROR: #1452 - Cannot add or update a child row: a foreign key
constraint fails (empology.students_skills, CONSTRAINT
students_skills_ibfk_2 FOREIGN KEY (skillid) REFERENCES skills
(skillid))
Am I on the right lines or not? I looked into joins also but this method made more sense to me.
Thanks for any help or useful links.
You have to make sure to use multiple-row insert syntax so that the LAST_INSERT_ID() stays consistent even though you're auto-incrementing another column:
INSERT INTO skills VALUES (NULL, 'test');
Say the skillid generated was 1, you can then do:
INSERT INTO student_skills VALUES
(NULL, 1, LAST_INSERT_ID()),
(NULL, 2, LAST_INSERT_ID()),
(NULL, 3, LAST_INSERT_ID()),
(NULL, 4, LAST_INSERT_ID());
The value returned by LAST_INSERT_ID() will consistently stay the same (1) throughout all four rows.
However, if you execute multiple inserts as standalone statements, LAST_INSERT_ID() will change as it will instead contain the generated auto-incremented value of each insert:
INSERT INTO student_skills VALUES (NULL, 1, LAST_INSERT_ID());
INSERT INTO student_skills VALUES (NULL, 2, LAST_INSERT_ID());
INSERT INTO student_skills VALUES (NULL, 3, LAST_INSERT_ID());
INSERT INTO student_skills VALUES (NULL, 4, LAST_INSERT_ID());
Where LAST_INSERT_ID() is the generated id of the immediate previous insert.
Take a look at this SQLFiddle Demo
Since students_skills.ssid is an AUTO_INCREMENT column, your second insert looks wrong. It seems you want the following:
INSERT INTO skills (skillid , skillname)
VALUES(NULL,'being grateful for help'); # generate ID by inserting NULL
INSERT INTO students_skills (ssid, studentid, skillid)
VALUES(NULL,'1', LAST_INSERT_ID()); # use ID in second table
It would be helpful to see the output of
SHOW CREATE TABLE skills;
SHOW CREATE TABLE students_skills;
to see the FOREIGN KEYs.
UPDATE TO SHOW OUTPUTS
+--------+------------------------------------------------------------------------------
| Table | Create Table
+--------+------------------------------------------------------------------------------
| skills | CREATE TABLE `skills` (
`skillid` int(11) NOT NULL AUTO_INCREMENT,
`skillname` varchar(30) NOT NULL,
PRIMARY KEY (`skillid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1 |
+--------+------------------------------------------------------------------------------
+-----------------+---------------------------------------------------------------------
| Table | Create Table
+-----------------+---------------------------------------------------------------------
| students_skills | CREATE TABLE `students_skills` (
`ssid` int(11) NOT NULL AUTO_INCREMENT,
`studentid` int(11) NOT NULL,
`skillid` int(11) NOT NULL,
PRIMARY KEY (`ssid`),
KEY `studentid` (`studentid`),
KEY `skillid` (`skillid`),
CONSTRAINT `students_skills_ibfk_1` FOREIGN KEY (`studentid`) REFERENCES `students` (`studentid`),
CONSTRAINT `students_skills_ibfk_2` FOREIGN KEY (`skillid`) REFERENCES `skills` (`skillid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 |
+-----------------+--------------------------------------------------------------------