Pau*_*ega 17 mysql foreign-keys mysql-error-1452
这似乎是一个常见的错误,但对于我的生活,我无法弄清楚这一点.
我在MySQL中有一组InnoDB用户表,通过外键绑定在一起; 父user表和一组存储电子邮件地址,操作等的子表.这些子user表都通过外键与父表绑定uid,并且所有父键和子键都是int(10).
所有子表都有一个uid值,其外键约束指向user.uid,并设置为ON DELETE CASCADE和ON UPDATE CASCADE.
当我从中删除用户时user,将删除所有子约束条目.但是,当我尝试更新user.uid值时,会导致以下错误,而不是将uid更改级联到子表:
#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)
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,我必须在这里遗漏一些明显的东西.删除键约束user_email并尝试更新值user导致相同的错误,但对于下一个按字母顺序排列的user子表,所以我不认为它是特定于表的错误.
编辑:
添加以下结果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
Run Code Online (Sandbox Code Playgroud)
Sid*_*pac 15
我通过将以下代码添加到SQL代码的开头来解决了我的" 外键约束失败 "问题(这是用于将值导入表)
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;
Run Code Online (Sandbox Code Playgroud)
然后将此代码添加到文件的末尾
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;
Run Code Online (Sandbox Code Playgroud)
wal*_*rii 10
由于您没有给出表定义,因此很难猜测.但看起来您正在尝试修改子表中的外键.AFAIK,这是非法的,你可以从父表修改它,但不能修改子表.
考虑这个例子:
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);
Run Code Online (Sandbox Code Playgroud)
然后这是允许的:
UPDATE parent
SET parent_id = 3 WHERE parent_id = 2;
SELECT * FROM parent;
SELECT * FROM child1;
SELECT * FROM child2;
Run Code Online (Sandbox Code Playgroud)
但这不是,因为它修改了子表中的父fk:
UPDATE child1
SET fk_parent_id = 4 WHERE fk_parent_id = 1;
Run Code Online (Sandbox Code Playgroud)
它得到的错误与您的错误非常相似:
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):
Run Code Online (Sandbox Code Playgroud)
在一项不相关的任务中,我最近在MySQL Workbench中启动了我们的 MySQL 数据库,当查看上述表的表关系时,我注意到我之前以某种方式错过的“重复”和/或虚假关系(它们没有显示)在 PHPMyAdmin FWIW 中)。删除这些额外的关系立即解决了问题。