MySQL 外键约束 - 错误 1452 - 无法添加或更新子行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14222967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MySQL Foreign key constraint - Error 1452 - Cannot add or update child row
提问by Calvin
I've used the other posts on this topic, but I'm having no luck.
我已经使用了关于这个主题的其他帖子,但我没有运气。
Here's the code I execute:
这是我执行的代码:
UPDATE tblOrderItems SET `ItemID` = 0004 WHERE `OrderNum`= 203 AND `OrderItemID` = 26
Here's my error:
这是我的错误:
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`))
Notes:
笔记:
- It happens when I either
INSERT
orUPDATE
intotblOrderItems
. tblCatalogItems
doeshave anItemID
of0004
. See: this
- 当我
INSERT
或UPDATE
进入tblOrderItems
. tblCatalogItems
确实有一个ItemID
的0004
。见:这个
Here are the create statements generated by MySQL Workbench:
以下是 MySQL Workbench 生成的 create 语句:
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$$
I tried the suggestion in thisrelevant post, but there were no results. This is a new database that hasn't actually been used yet; I've just filled it with fake data. Any ideas would be greatly appreciated.
我尝试了这篇相关帖子中的建议,但没有结果。这是一个尚未实际使用的新数据库;我刚刚用假数据填充了它。任何想法将不胜感激。
回答by Joachim Isaksson
There is a foreign key constraint on tblOrderItems
that its ItemID
needs to reference an ItemID
that already exists in tblCatalogItems
.
有一个外键约束tblOrderItems
,它ItemID
需要引用ItemID
已经存在于tblCatalogItems
.
CONSTRAINT `ItemID` FOREIGN KEY (`ItemID`) REFERENCES `tblCatalogItems` (`ItemID`),
The message only means that you're trying to update tblOrderItems
to reference the item in tblCatalogItems
with ItemID
= 0004, but that item does not exist.
该消息仅表示您正在尝试更新tblOrderItems
以引用tblCatalogItems
with ItemID
= 0004 中的项目,但该项目不存在。
Since ItemID
is a varchar, you probably want to quote the 0004
or it may be converted to an int 4
before conversion to varchar. That may be your problem if the row with ItemID
= 0004 actually exists.
由于ItemID
是 varchar,您可能希望引用 the0004
或者4
在转换为 varchar 之前将其转换为 int 。如果ItemID
= 0004的行确实存在,那可能是您的问题。
UPDATE tblOrderItems SET `ItemID` = '0004' WHERE `OrderNum`= 203 AND `OrderItemID` = 26
回答by Chamila Chulatunga
Without seeing the table data I can't be sure, but I'm guessing it's because there is no record in tblCatalogItems
with an ItemID
of '0004'.
在没有看到表中的数据我不能肯定,但我猜这是因为在没有记录tblCatalogItems
与ItemID
的“0004”。
Also, you probably need to quote the 0004
in your update statement since the column is defined as character (varchar(10)
) not number (int
).
此外,您可能需要0004
在更新语句中引用 the ,因为该列被定义为字符 ( varchar(10)
) 而不是数字 ( int
)。
There is a foreign key relationship defined between tblCatalogItems.ItemId
and tblOrderItems.ItemId
which means that any row in tblOrderItems
can only have a value for ItemId
that matches an ItemId
found in tblCatalogItems
.
在tblCatalogItems.ItemId
和之间定义了外键关系,tblOrderItems.ItemId
这意味着中的任何行tblOrderItems
只能具有ItemId
与 中ItemId
找到的匹配的值tblCatalogItems
。
You would therefore need to insert a record into 'tblCatalogItems' with an ItemId
of '0004' first, before running your update on tblOrderItems
因此ItemId
,在运行更新之前,您需要先将记录插入到 'tblCatalogItems' 中,其值为 '0004'tblOrderItems
Alternatively you need to change the SET ItemID =
clause in your update to set a value that matches to an ItemId
value that actually exists in the tblCatalogItems
table
或者,您需要更改SET ItemID =
更新中的子句以设置与表ItemId
中实际存在的值匹配的值tblCatalogItems
回答by troelskn
The data type needs to match on both sides of your foreign key constraint. Here you have a varchar(50)
referring a varchar(10)
, which isn't allowed.
数据类型需要在外键约束的两侧匹配。这里有一个varchar(50)
引用 a 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$$