MySQL 外键约束 - 错误 1452 - 无法添加或更新子行

Posted

技术标签:

【中文标题】MySQL 外键约束 - 错误 1452 - 无法添加或更新子行【英文标题】:MySQL Foreign key constraint - Error 1452 - Cannot add or update child row 【发布时间】:2012-12-22 18:39:00 【问题描述】:

我已经使用了关于这个主题的其他帖子,但我没有运气。

这是我执行的代码:

UPDATE tblOrderItems SET `ItemID` = 0004 WHERE `OrderNum`= 203 AND `OrderItemID` = 26

这是我的错误:

Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`cai0066`.`tblOrderItems`, CONSTRAINT `ItemID` FOREIGN KEY (`ItemID`) REFERENCES `tblCatalogItems` (`ItemID`))

注意事项:

    当我将INSERTUPDATE 转换为tblOrderItems 时,就会发生这种情况。 tblCatalogItems 确实ItemID0004。见:this

以下是 mysql Workbench 生成的创建语句:

delimiter $$

CREATE TABLE `tblCatalogItems` (
  `ItemID` varchar(10) NOT NULL DEFAULT '',
  `ItemName` varchar(50) DEFAULT NULL,
  `Wholesale` decimal(10,2) DEFAULT NULL,
  `Cost5-10` decimal(10,2) DEFAULT NULL,
  `Cost11-19` decimal(10,2) DEFAULT NULL,
  `Cost20` decimal(10,2) DEFAULT NULL,
  `Retail` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`ItemID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$


delimiter $$

CREATE TABLE `tblItemCosts` (
  `Cost` decimal(10,2) DEFAULT NULL,
  `VendorID` int(11) NOT NULL,
  `ItemID` varchar(10) NOT NULL,
  KEY `VendorID_idx` (`VendorID`),
  KEY `ItemID_idx` (`ItemID`),
  CONSTRAINT `VendorID` FOREIGN KEY (`VendorID`) REFERENCES `tblVendors` (`VendorID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$


delimiter $$

CREATE TABLE `tblOrderItems` (
  `OrderItemID` int(11) NOT NULL AUTO_INCREMENT,
  `OrderNum` int(11) NOT NULL,
  `PayPalTxnID` int(10) DEFAULT NULL,
  `Description` varchar(225) DEFAULT NULL,
  `Quantity` int(11) DEFAULT NULL,
  `UnitPrice` decimal(10,2) DEFAULT NULL,
  `ItemStatus` varchar(30) DEFAULT NULL,
  `TrackingNumber` varchar(50) DEFAULT NULL,
  `ShippingCost` decimal(10,2) DEFAULT NULL,
  `ItemID` varchar(50) DEFAULT NULL,
  `TotalPrice` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`OrderItemID`,`OrderNum`),
  UNIQUE KEY `PayPalTxnID_UNIQUE` (`PayPalTxnID`),
  KEY `PayPalTxnID_idx` (`PayPalTxnID`),
  KEY `UnitPrice_idx` (`ItemID`),
  KEY `OrderNum_idx` (`OrderNum`),
  CONSTRAINT `ItemID` FOREIGN KEY (`ItemID`) REFERENCES `tblCatalogItems` (`ItemID`),
  CONSTRAINT `OrderNum` FOREIGN KEY (`OrderNum`) REFERENCES `tblOrders` (`OrderNum`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `UnitPrice` FOREIGN KEY (`ItemID`) REFERENCES `tblCatalogItems` (`ItemID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=7678 DEFAULT CHARSET=latin1$$


delimiter $$

CREATE TABLE `tblOrderItemStatus` (
  `OrderItemID` int(11) NOT NULL,
  `OrderDate` varchar(12) DEFAULT NULL,
  `DesignProofSent` varchar(12) DEFAULT NULL,
  `SubmittedToProduction` varchar(12) DEFAULT NULL,
  `InProduction` varchar(12) DEFAULT NULL,
  `Shipped` varchar(12) DEFAULT NULL,
  PRIMARY KEY (`OrderItemID`),
  UNIQUE KEY `OrderItemID_UNIQUE` (`OrderItemID`),
  KEY `OrderItemID_idx` (`OrderItemID`),
  CONSTRAINT `OrderItemID` FOREIGN KEY (`OrderItemID`) REFERENCES `tblOrderItems` (`OrderItemID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$


delimiter $$

CREATE TABLE `tblOrders` (
  `OrderNum` int(11) NOT NULL AUTO_INCREMENT,
  `PayPalTxnID` int(10) DEFAULT NULL,
  `OrderDate` varchar(50) DEFAULT NULL,
  `OrderStatus` varchar(10) DEFAULT 'New',
  `RushFlag` bit(1) DEFAULT b'0',
  `ShipName` varchar(50) DEFAULT NULL,
  `ShipEmail` varchar(100) DEFAULT NULL,
  `ShipAddress1` varchar(50) DEFAULT NULL,
  `ShipAddress2` varchar(50) DEFAULT NULL,
  `ShipCity` varchar(50) DEFAULT NULL,
  `ShipState` char(2) DEFAULT NULL,
  `ShipZip` varchar(10) DEFAULT NULL,
  `ShippingCharge` decimal(10,2) DEFAULT NULL,
  `TotalCost` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`OrderNum`),
  UNIQUE KEY `PayPalTxnID_UNIQUE` (`PayPalTxnID`)
) ENGINE=InnoDB AUTO_INCREMENT=346 DEFAULT CHARSET=latin1$$


delimiter $$

CREATE TABLE `tblVendors` (
  `VendorID` int(11) NOT NULL,
  `VendorName` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`VendorID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$

我尝试了this相关帖子中的建议,但没有结果。这是一个尚未实际使用的新数据库;我刚刚用假数据填充了它。任何想法将不胜感激。

【问题讨论】:

你试过在tblCatalogItems上做UPDATE吗? 我将编辑我的帖子以包含以下内容:当我将INSERTUPDATE 转换为tblOrderItems 时会发生这种情况。我不想创建新的目录项目,我想从目录中提取项目并进入订单。我希望这可以解决一些问题。 你有SET ItemID = 0004ItemID 是varchar。如果父表中存在这样的项目,请尝试SET ItemID = '0004' 这就是问题所在。我不敢相信。谢谢。 【参考方案1】:

tblOrderItems 上有一个外键约束它的ItemID 需要引用ItemID 已经存在于tblCatalogItems 中的ItemID

CONSTRAINT `ItemID` FOREIGN KEY (`ItemID`) REFERENCES `tblCatalogItems` (`ItemID`),

该消息仅表示您正在尝试更新tblOrderItems 以使用ItemID= 0004 引用tblCatalogItems 中的项目,但该项目不存在。

由于ItemID 是一个varchar,您可能希望引用0004,或者在转换为varchar 之前将其转换为int 4。如果ItemID = 0004 的行确实存在,那可能是您的问题。

UPDATE tblOrderItems SET `ItemID` = '0004' WHERE `OrderNum`= 203 AND `OrderItemID` = 26

【讨论】:

我刚摘掉眼镜,因为我整天都在研究这个,这是一个类型问题。谢谢你。一些ItemIDs 中有字符,所以我只需要引用它们。再次感谢!【参考方案2】:

没有看到表格数据我无法确定,但我猜这是因为tblCatalogItems 中没有记录为“0004”的ItemID

此外,您可能需要在更新语句中引用 0004,因为该列被定义为字符 (varchar(10)) 而不是数字 (int)。

tblCatalogItems.ItemIdtblOrderItems.ItemId 之间定义了外键关系,这意味着tblOrderItems 中的任何行只能具有与tblCatalogItems 中的ItemId 匹配的ItemId 值。

因此,在tblOrderItems 上运行更新之前,您需要先将一条记录插入到“tblCatalogItems”,其中ItemId 为“0004”

或者,您需要更改更新中的SET ItemID = 子句,以设置与ItemId 值匹配的值,该值实际存在于tblCatalogItems 表中

【讨论】:

【参考方案3】:

数据类型需要在外键约束的两边都匹配。在这里,您有一个 varchar(50) 引用 varchar(10),这是不允许的。

CREATE TABLE `tblCatalogItems` (
  `ItemID` varchar(10) NOT NULL DEFAULT '',
  ...
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$

...

CREATE TABLE `tblOrderItems` (
  `ItemID` varchar(50) DEFAULT NULL,
  ...
  CONSTRAINT `UnitPrice` FOREIGN KEY (`ItemID`) REFERENCES `tblCatalogItems` (`ItemID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=7678 DEFAULT CHARSET=latin1$$

【讨论】:

以上是关于MySQL 外键约束 - 错误 1452 - 无法添加或更新子行的主要内容,如果未能解决你的问题,请参考以下文章

Magento DB错误:完整性约束违规:1452无法添加或更新子行:外键约束失败

MySQL 中的外键约束错误 1452 - Magento 导入

SQL 错误:SQLSTATE [23000]:完整性约束违规:1452 无法添加或更新子行:外键约束失败

ERROR 1452:无法添加或更新子行:外键约束失败

完整性约束违规:1452 无法添加或更新子行:外键约束失败

完整性约束违规:1452 无法添加或更新子行:外键约束失败(Laravel 应用程序)