Mysql错误1452 -无法添加或更新子行:外键约束失败

浏览 266关注 0回答 15得票数 243
原文

我有点奇怪的问题。我正尝试将一个外键添加到一个引用另一个表的表中,但由于某种原因,它失败了。由于我对MySQL的了解有限,唯一可能令人怀疑的是,在另一个表上有一个外键引用了我试图引用的那个外键。

我已经在两个表上执行了SHOW CREATE TABLE查询,sourcecodes_tags是带有外键的表,sourcecodes是被引用的表。

CREATE TABLE `sourcecodes` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` int(11) unsigned NOT NULL,
 `language_id` int(11) unsigned NOT NULL,
 `category_id` int(11) unsigned NOT NULL,
 `title` varchar(40) CHARACTER SET utf8 NOT NULL,
 `description` text CHARACTER SET utf8 NOT NULL,
 `views` int(11) unsigned NOT NULL,
 `downloads` int(11) unsigned NOT NULL,
 `time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`),
 KEY `language_id` (`language_id`),
 KEY `category_id` (`category_id`),
 CONSTRAINT `sourcecodes_ibfk_3` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `sourcecodes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `sourcecodes_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

CREATE TABLE `sourcecodes_tags` (
 `sourcecode_id` int(11) unsigned NOT NULL,
 `tag_id` int(11) unsigned NOT NULL,
 KEY `sourcecode_id` (`sourcecode_id`),
 KEY `tag_id` (`tag_id`),
 CONSTRAINT `sourcecodes_tags_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

以下是生成错误的代码:

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
原文
Zoe修改于2019-05-24 21:20

15 个回答

高票数最新
Jannis
修改于2014-11-26 12:16
得票数 229

您的sourcecodes_tags表很可能包含不再存在于sourcecodes表中的sourcecode_id值。你必须先摆脱它们。

下面是一个可以找到这些ID的查询:

SELECT DISTINCT sourcecode_id FROM 
   sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id 
WHERE sc.id IS NULL;
fyrye
回答于2011-10-22 04:42
得票数 16

如果child.column的值已经为0,并且没有parent.id值为0,则将外键parent.id设置为child.column时也会发生这种情况

您需要确保每个child.column为NULL或具有parent.id中存在的值

现在我读了诺斯写的声明,这就是他要验证的。

VHanded
回答于2012-01-09 17:49
得票数 4

我最终删除了表中的所有数据,然后再次运行alter。它起作用了。不是很出色,但它节省了很多时间,特别是你的应用程序还在开发阶段,没有任何客户数据。

Mostafa Norzade
修改于2019-05-22 15:16
得票数 104

我的MySQL数据库也有同样的问题,但最终,我得到了一个对我有效的解决方案。

因为在我的表中,从mysql的角度来看一切都很好(两个表都应该使用InnoDB引擎,并且每列的数据类型都应该是相同的类型,这是外键约束的一部分)。

我所做的唯一一件事就是禁用外键检查,然后在执行外键操作后启用它。

我采取的步骤:

SET foreign_key_checks = 0;
alter table tblUsedDestination add constraint f_operatorId foreign key(iOperatorId) references tblOperators (iOperatorId); Query
OK, 8 rows affected (0.23 sec) Records: 8  Duplicates: 0  Warnings: 0
SET foreign_key_checks = 1;
MarthyM
修改于2015-06-05 17:37
得票数 2

我在三次不同的时候遇到了完全相同的问题。在每个实例中,这都是因为我的一个(或多个)记录不符合新的外键。在尝试添加键本身之前,您可能希望更新现有记录以遵循外键的语法约束。以下示例通常应隔离问题记录:

SELECT * FROM (tablename)
    WHERE (candidate key) <> (proposed foreign key value) 
        AND (candidate key) <> (next proposed foreign key value)

在查询中对外键中的每个值重复AND (candidate key) <> (next proposed foreign key value)

如果您有大量记录,这可能会很困难,但如果您的表相当小,则不会花费太长时间。我对SQL语法不是很在行,但对我来说,这始终是一个孤立的问题。

Mostafa Norzade
修改于2019-05-22 15:17
得票数 5

我遇到了同样的问题,我检查了我的表的行,发现与我想要定义外键的字段的值有一些不兼容。我纠正了这些值,再试一次,问题就解决了。

Mostafa Norzade
修改于2019-05-22 15:12
得票数 17

对我来说,这个问题有点不同,非常容易检查和解决。

您必须确保两个表都是InnoDB。如果其中一个表(即引用表)是MyISAM,则约束将失败。

    SHOW TABLE STATUS WHERE Name =  't1';

    ALTER TABLE t1 ENGINE=InnoDB;
MarthyM
修改于2015-06-05 18:19
得票数 2

清空两个表的数据并运行命令。看起来不错。

naXa
回答于2016-02-23 22:29
得票数 0
UPDATE sourcecodes_tags
SET sourcecode_id = NULL
WHERE sourcecode_id NOT IN (
  SELECT id FROM sourcecodes);

应该有助于去掉那些身份证。或者,如果sourcecode_id中不允许使用null,则删除这些行或将缺少的值添加到sourcecodes表中。

CesareoAguirre
回答于2016-03-16 09:40
得票数 1

我正在准备这个解决方案,这个例子可能会有所帮助。

我的数据库有两个表(email和credit_card),它们的ID都有主键。另一个表(client)将该表的ID引用为外键。我有理由将电子邮件与客户数据分开。

首先,我插入被引用的表(email,credit_card)的行数据,然后获取每个表的ID,这些ID在第三个表(client)中是需要的。

如果您不先在被引用的表中插入行,那么当您在第三个表中插入引用外键的新行时,MySQL将无法建立对应关系。

如果首先插入被引用表的被引用行,然后插入引用外键的行,则不会发生错误。

希望这能有所帮助。

twigg
回答于2016-12-02 19:42
得票数 2

我在使用Laravel和eloquent时遇到了这个错误,试图创建一个外键链接会导致1452。问题是链接表中缺少数据。

请查看此处的示例:http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/

akelec
回答于2017-01-31 15:55
得票数 0

我遇到了同样的问题,并找到了解决方案,在外键列上放置NULL而不是NOT NULL。下面是一个查询:

ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

MySQL已执行此查询!

rink.attendant.6
修改于2017-07-25 10:39
得票数 4

尝尝这个

SET foreign_key_checks = 0;

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE

SET foreign_key_checks = 1;
Kingsley Mitchell
修改于2018-03-19 05:43
得票数 1

确保该值在另一个表中,否则将在分配的相应列中收到此错误。

因此,如果分配的列被分配给另一个表的行id,请确保表中有行,否则将出现此错误。

Shamal Sabah
回答于2019-10-07 15:50
得票数 0

在我的例子中,我创建了一个具有相同结构的新表,创建了与其他表的关系,然后从有问题的旧表中提取CSV中的数据,然后将CSV导入到新表中,并禁用外键检查和禁用导入中断,我所有的数据都插入到没有问题的新表中,然后删除旧表。

这对我很管用。

页面原文内容由Zim、Zoe、nos、Jannis、naXa、Meloman、Ryan、fyrye、VHanded、Prakash、Mostafa Norzade、cs_alumnus、Armfoot、Omar Dulaimi、mopsyd、MarthyM、Mostafa -T、zmonteca、VijayRana、xlecoustillier、CesareoAguirre、twigg、akelec、Carlo Guevarra、rink.attendant.6、Kingsley Mitchell、Shamal Sabah提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:https://stackoverflow.com/questions/1253459复制

扫码关注云+社区

领取腾讯云代金券