mysql - what does this error mean? - mysql

I do not require this error to be solved. I just need to understand what it means so I can approach it myself.
Cannot add or update a child row: a foreign key constraint fails
(`db`.`transaction`, CONSTRAINT `transaction_ibfk_2`
FOREIGN KEY (`product_id`) REFERENCES `product` (`id`))
INSERT INTO `transaction` ( `client_id`, `cost`, `website_id`, `product_id`,
`template_number`, `value`, `order_id` )
VALUES ( '17', '', '2480', '', '', '12', '1');
What is a foreign key? How is it set?
What does CONSTRAINT transaction_ibfk_2 mean?
Does this mean I need to have a table called transaction_ibfk_2?
Thanks.

You are inserting an empty string as productid (Fourth item in the list)
INSERT INTO transaction
(client_id, cost, website_id, product_id, template_number, value, order_id)
VALUES ('17', '', '2480', '', '', '12', '1')
There is a referential integrity constraint set up to ensure that you must only insert productids matching one in the referenced product table.

This means you are trying to add a value into the foreign key column which is not available in the referenced column or trying to add blank in foreign key column.
i.e. You are trying to add product_id as blank which is not allowed. All values in foreign key column must be valid values present in the main referenced column id.

There's not necessarily a relationship between constraint names and tables although most people name them appropriately to make their lives easier.
All this means is that you have a transaction_ibfk_2 constraint. The actual problem is in the rest of the message:
FOREIGN KEY (product_id) REFERENCES product (id)
You need to insert a row into your product table first. The id that you insert there should be the product_id you're trying to insert into transaction (which is '' for some reason - I'm pretty certain this should be a real value (or possibly NULL)).
You can create foreign keys with a clause of the create table or alter table DDL statements.

Related

Cannot add or update a child row: a foreign key constraint fails when trying to add a new row

I'm currently trying to add a new entry in a table. In this table I've a constraint to my users table (the user id). In some cases my user id can be not set yet. In the case it's empty, I'm getting an error:
Cannot add or update a child row: a foreign key constraint fails
This is how I setup my constraint:
So is there a way to insert an empty value to a constraint field? If no, what would be the best solution instead of removing the constraint?
So is there a way to insert an empty value to a constraint field?
Yes, there is. As long as the column controlled by the foreign key is not defined as NOT NULL, you can insert a NULL value into it, as explain in the manual. What is not allowed is to insert a non-NULL value that does not exists in the parent table (this includes the empty string!).
MySQL essentially implements the semantics defined by MATCH SIMPLE, which permit a foreign key to be all or partially NULL. In that case, the (child table) row containing such a foreign key is permitted to be inserted, and does not match any row in the referenced (parent) table.
Consider this demo on DB Fiddlde:
-- parent table
create table parent (id int primary key);
-- child table
create table child (
id int primary key,
parent_id int null, -- allow `NULL` values
constraint parent_id_fk foreign key(parent_id) references parent(id)
);
-- create a parent record
insert into parent(id) values(1);
-- insert a child record that references the parent: ok
insert into child(id, parent_id) values(1, 1);
-- insert a child record with a NULL parent_id : ok
insert into child(id, parent_id) values(2, NULL);
-- insert a child record with a (non-NULL) unknown parent_id
insert into child(id, parent_id) values(3, 2);
-- Error: Cannot add or update a child row: a foreign key constraint fails

Can't insert values into table, foreign key constraint keeps failing

I'm trying to insert this code into my Albums table on my MySQL database
INSERT INTO `Albums` (`Albumid`, `Name`, `Numberoftracks`, `Artistid`, ]
`Genre`) VALUES (1, "Innuendo", 12, "Queen", "Rock");
But every time I try to I keep getting this error.
1452 - Cannot add or update a child row: a foreign key constraint fails
(`b4014107_db1/Albums`, CONSTRAINT `Albums_ibfk_1` FOREIGN KEY (`Artistid`)
REFERENCES `Artist` (`Artistid`))
I know it's something to do with my foreign key within the table, but I need to manually enter the foreign key because it's not auto-incremented.
Here's the tables code.
CREATE TABLE `Albums` ( `Albumid` int(6) NOT NULL, `Name` varchar(50) NOT
NULL, `Numberoftracks` int(11) NOT NULL, `Artistid` int(6) NOT NULL,
`Genre` varchar(50) NOT NULL, PRIMARY KEY (`Albumid`), KEY `Artistid`
(`Artistid`), CONSTRAINT `Albums_ibfk_1` FOREIGN KEY (`Artistid`)
REFERENCES `Artist` (`Artistid`)) ENGINE=InnoDB DEFAULT CHARSET=latin1
How do I fix this? I need to input data into the table.
artistid is a foreign key in the table Albums. Parent child relationship error comes when you try to insert a foreign key in child table which is not present in the parent table. artistid is not present in your Artist table.
Also, to add the the datatype of artistid is also different.
Taken from mysql docs
Foreign key relationships involve a parent table that holds the
central data values, and a child table with identical values pointing
back to its parent. The FOREIGN KEY clause is specified in the child
table.
It will reject any INSERT or UPDATE operation that attempts to create
a foreign key value in a child table if there is no a matching
candidate key value in the parent table.
To remove your error, insert the Queens artist in your Artist table first and then you can insert it into Albums table. Also correct the datatype of column artistid.
Using foreign keys doesn't mean any implicit auto-incrementation. A foreign key in a table means that a record must already exist in another.
see http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html (change version in the url regarding your needs)
Otherwise, make a trigger if you want the artist to be dynamically created.
Hope it'll clarify.

Clarification - Default Foreign Key Constraints - InnoDB

MySQL Server version: 5.6.17
I have two tables:
vatbands:
`vatbands_id` INT(11) UNSIGNED NOT NULL,
`client_id` INT(11) UNSIGNED NOT NULL COMMENT 'Customer ID',
`code` ENUM('A', 'B', 'C', 'D', 'E', 'F') NOT NULL,
PRIMARY KEY (`vatbands_id`, `code`, `client_id`),
INDEX `vatcode_vatbands` (`code` ASC, `client_id` ASC)
ENGINE = InnoDB;
1 row in vatbands:
INSERT INTO `vatbands` (`client_id`, `code`) VALUES ('1', 'A');
items:
`client_id` INT(11) UNSIGNED NOT NULL,
`vatcode` ENUM('A', 'B', 'C', 'D', 'E', 'F') NOT NULL DEFAULT 'A',
PRIMARY KEY (`item_id`, `client_id`),
INDEX `vatcode_item` (`vatcode` ASC, `client_id` ASC),
CONSTRAINT `vatcode_item`
FOREIGN KEY (`vatcode` , `client_id`)
ENGINE = InnoDB;
Inserting into child (item) table:
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', '');
When I try to insert into my items table without specifying a vatcode i get foreign key constraint failure:
Cannot add or update a child row: a foreign key constraint fails (`mydb`.`item`, CONSTRAINT `vatcode_item` FOREIGN KEY (`vatcode`, `client_id`) REFERENCES `vatbands` (`code`, `client_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Why is this, I thought specifying a default value for the vatcode would allow this to continue (as long as the row exists)?
I have checked the InnoDB manual:
14.6.6 InnoDB and FOREIGN KEY Constraints
Referential actions for foreign keys of InnoDB tables are subject to
the following conditions:
While SET DEFAULT is allowed by the MySQL Server, it is rejected as
invalid by InnoDB.
Is this the reason it is failing?
UPDATE:
If i input a value directly using PHP:
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', 'A');
The constraint succeeds as expected.
The SET DEFAULT clause for a foreign key has nothing to do with inserting to the child table. It declares what to do with dependent rows in the child table if the referenced row in the parent table is deleted or updated.
Example: If an employee belongs to a department, and the department is deleted, should the employee be fired as well? Or should they be reassigned to some other "default" department?
I tested your example, and I find that it works fine, but you must specify at least a client_id that exists in the parent table.
mysql> insert into items (client_id) values (1);
Query OK, 1 row affected (0.00 sec)
I also notice that your key in vatbands on (code,client_id) is a non-unique key. It should really be a primary key or unique key to be referenced by a foreign key of a child table. In fact, when I test with MySQL 5.7 milestone release, I can't even create the items table because apparently in this regard the new version of MySQL is more strict than older versions. So I had to make your key a primary key. Then the test worked.
The only way I could get this to work is inserting a default using PHP.
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', 'A');
If anyone has any better ways of resolving this please don't hesitate to comment, I would much prefer a pure MySQL method.
If you use:
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', '');
You are not inserting NULL but an empty string.
INSERT INTO `item` (`client_id`, `code`) VALUES ('1', NULL);
will work

MySQL - Cannot add or update a child row: a foreign key constraint fails

This seems to be a common error, but for the life of me I can't figure this out.
I have a set of InnoDB user tables in MySQL that are tied together via foreign key; the parent user table, and a set of child tables that store email addresses, actions, etc. These are all tied to the parent user table by a foreign key, uid, with all of the parent and child keys being int(10).
All of the child tables have a uid value with a foreign key constraint pointing to user.uid, and set to ON DELETE CASCADE and ON UPDATE CASCADE.
When I delete a user from user, all of the child constrained entries are removed. However, when I attempt to update a user.uid value, it results in the following error, rather than cascading the uid change to the child tables:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`accounts`.`user_email`, CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE)
I have a feeling I must be missing something obvious here. Removing the key constraint with user_email and attempting to update the value in user results in the same error but for the next alphabetical user child table, so I don't believe it is a table-specific error.
EDIT:
Adding in the results from SHOW ENGINE INNODB STATUS:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
121018 22:35:41 Transaction:
TRANSACTION 0 5564387, ACTIVE 0 sec, process no 1619, OS thread id 2957499248 updating or deleting, thread declared inside InnoDB 499
mysql tables in use 1, locked 1
17 lock struct(s), heap size 2496, 9 row lock(s), undo log entries 2
MySQL thread id 3435659, query id 24068634 localhost root Updating
UPDATE `accounts`.`user` SET `uid` = '1' WHERE `user`.`uid` = 306
Foreign key constraint fails for table `accounts`.`user_email`:
,
CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index `uid` tuple:
DATA TUPLE: 2 fields;
...
A bunch of hex code
But in parent table `accounts`.`user`, in index `PRIMARY`,
the closest match we can find is record:
...
A bunch of hex code
I solved my 'foreign key constraint fails' issues by adding the following code to the start of the SQL code (this was for importing values to a table)
SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT;
SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS;
SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION;
SET NAMES utf8;
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
SET #OLD_SQL_NOTES=##SQL_NOTES, SQL_NOTES=0;
Then adding this code to the end of the file
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
SET CHARACTER_SET_CLIENT=#OLD_CHARACTER_SET_CLIENT;
SET CHARACTER_SET_RESULTS=#OLD_CHARACTER_SET_RESULTS;
SET COLLATION_CONNECTION=#OLD_COLLATION_CONNECTION;
SET SQL_NOTES=#OLD_SQL_NOTES;
Since you haven't given table definitions, it's hard to guess. But it looks like you are attempting to modify the foreign key in the child table. AFAIK, this is illegal, you can modify it from the parent, but not the child table.
Consider this example:
CREATE TABLE parent (
parent_id INT NOT NULL,
parent_data int,
PRIMARY KEY (parent_id)
) ENGINE=INNODB;
CREATE TABLE child1 (
child1_id INT,
child1_data INT,
fk_parent_id INT,
INDEX par_ind1 (fk_parent_id),
FOREIGN KEY (fk_parent_id)
REFERENCES parent(parent_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=INNODB;
CREATE TABLE child2 (
child2_id INT,
child2_data INT,
fk_parent_id INT,
INDEX par_ind2 (fk_parent_id),
FOREIGN KEY (fk_parent_id)
REFERENCES parent(parent_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=INNODB;
INSERT INTO parent
(parent_id, parent_data)
VALUES
(1, 11),
(2, 12);
INSERT INTO child1
(child1_id, child1_data, fk_parent_id)
VALUES
(101, 1001, 1),
(102, 1002, 1),
(103, 1003, 1),
(104, 1004, 2),
(105, 1005, 2);
INSERT INTO child2
(child2_id, child2_data, fk_parent_id)
VALUES
(106, 1006, 1),
(107, 1007, 1),
(108, 1008, 1),
(109, 1009, 2),
(110, 1010, 2);
Then this is allowed:
UPDATE parent
SET parent_id = 3 WHERE parent_id = 2;
SELECT * FROM parent;
SELECT * FROM child1;
SELECT * FROM child2;
But this is not, because it modifies the parent fk from the child table:
UPDATE child1
SET fk_parent_id = 4 WHERE fk_parent_id = 1;
It gets an error very similar to your error:
Cannot add or update a child row: a foreign key constraint fails (`db_2_b43a7`.`child1`, CONSTRAINT `child1_ibfk_1` FOREIGN KEY (`fk_parent_id`) REFERENCES `parent` (`parent_id`) ON DELETE CASCADE ON UPDATE CASCADE):
I had faced same issue while creating foreign constraints on table. the simple way of coming out of this issue are first take backup of your parent and child table then truncate child table and again try to make a relation. hope this will solve the problem.
Even though this is pretty old, just chiming in to say that what is useful in #Sidupac's answer is the FOREIGN_KEY_CHECKS=0.
This answer is not an option when you are using something that manages the database schema for you (JPA in my case) but the problem may be that there are "orphaned" entries in your table (referencing a foreign key that might not exist).
This can often happen when you convert a MySQL table from MyISAM to InnoDB since referential integrity isn't really a thing with the former.
On an unrelated task, I recently brought up our MySQL database in MySQL Workbench, and when viewing the table relations for the above tables, I noticed 'duplicate' and/or spurious relations that I had somehow missed before (they weren't showing up in PHPMyAdmin FWIW). Removing these extra relations cleared up the issue immediately.
Such an error on update may be caused by the difference in character set and collation so make sure they are the same for both tables.
My fix for this was my child table needed to be populated before the parent table.
I had two tables: UserDetails and Login linked by an email address. I therefore had to insert into the UserDetails first before inserting into the Login table:
insert into UserDetails (Email, Name, Telephone, Department) values ('Email', 'Name', 'number', 'IT');
Then:
insert into Login (UserID, UserType, Email, Username, Password) VALUES (001, 'SYS-USR-ADMIN', 'Email', 'Name', 'Password')
I've faced this issue and the solution was making sure that all the data from the child field are matching the parent field
for example, you want to add foreign key inside (attendance) table to the column (employeeName)
where the parent is (employees) table, (employeeName) column
all the data in attendance.employeeName must be matching employee.employeeName
I had the same problem but when I looked closely I found that, it was causing because I was trying to put the foreign key values into the tables before that key was assigned its primary key value. e.g.
I had two tables "customers" and "films", "cust_id" and "film_id" were primary key respectively. "customer" had one-to-many relation with "films" so I had "cust_id" as foreign key in "films" tables. But I was trying to put values to "films" table first, so I got that problem.
Hope this will assist anyone having the same error while importing CSV data into related tables. In my case the parent table was OK, but I got the error while importing data to the child table containing the foreign key. After temporarily removing the foregn key constraint on the child table, I managed to import the data and was suprised to find some of the values in the FK column having values of 0 (obviously this had been causing the error since the parent table did not have such values in its PK column). The cause was that, the data in my CSV column preceeding the FK column contained commas (which I was using as a field delimeter). Changing the delimeter for my CSV file solved the problem.

sql: change primary key to another list of unique elements

i want to change the ids of a table to some other unique value.
This is a simplified example:
CREATE TABLE IF NOT EXISTS test (
id int(11) NOT NULL,
reverse_id int(11) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY reverse_id (reverse_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO test (id, reverse_id) VALUES ('1', '2'), ('2', '1');
UPDATE test SET id = reverse_id;
# Duplicate entry '2' for key 'PRIMARY'
I am looking for a command that checks only at the end of the UPDATE for the uniqueness of the id elements.
[I know that I can create a second row and change the status of this row to primary, then i can update the ids and reset the primary status, but i want to have one command, without adding or changing other rows, tables]
This is not possible with MySQL as far as I know.
It neither evaluates constraint on statement level (it does that on row level while processing) nor does it allow you to define them to be deferred (so the constraint would be evaluated at commit time).
The only option I can see if you want to "renumber" your primary key: drop the primary key, renumber the ids then re-create the primary key.
What if you create the table having reverse_id as its primary key? - that is unique in your definition so it is a valid candidate for primary key.
Primary keys are unique by definition - this constraint is stopping you from achieving what you want