我有以下表格:
CREATE TABLE IF NOT EXISTS `Person_Categories` (
`PrsCatID` int(11) NOT NULL auto_increment,
`PrsCategory` varchar(45) NOT NULL,
PRIMARY KEY (`PrsCatID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;
CREATE TABLE IF NOT EXISTS `Persons` (
`PersonID` int(11) NOT NULL auto_increment,
`FirstName` varchar(45) NOT NULL,
`LastName` varchar(45) NOT NULL,
`OrderName` varchar(45) default NULL,
`Email` varchar(45) NOT NULL,
`Telephone` varchar(20) default NULL,
`Mobile` varchar(20) default NULL,
`StreetAddress` varchar(45) NOT NULL,
`City` varchar(45) NOT NULL,
`RegionID` int(2) NOT NULL,
`PostCode` varchar(10) NOT NULL,
`CountryID` int(11) NOT NULL,
`TitleID` int(11) NOT NULL,
`CIC_MailingList` tinyint(1) NOT NULL,
`FoundationMember` tinyint(1) NOT NULL,
`PersonCmts` mediumtext,
PRIMARY KEY (`PersonID`),
KEY `TitleID` (`TitleID`),
KEY `RegionID` (`RegionID`),
KEY `CountryID` (`CountryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
CREATE TABLE IF NOT EXISTS `Persons_PersonCategories` (
`PersonID` int(11) NOT NULL,
`PrsCatID` int(11) NOT NULL,
PRIMARY KEY (`PersonID`,`PrsCatID`),
KEY `PrsCatID` (`PrsCatID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Constraints for the tables
--
ALTER TABLE `Persons`
ADD CONSTRAINT `Persons_ibfk_12` FOREIGN KEY (`TitleID`) REFERENCES `Job_Titles` (`TitleID`),
ADD CONSTRAINT `Persons_ibfk_14` FOREIGN KEY (`CountryID`) REFERENCES `Countries` (`CountryID`),
ADD CONSTRAINT `Persons_ibfk_15` FOREIGN KEY (`RegionID`) REFERENCES `Regions` (`RegionID`);
ALTER TABLE `Persons_PersonCategories`
ADD CONSTRAINT `Persons_PersonCategories_ibfk_8` FOREIGN KEY (`PrsCatID`) REFERENCES `Person_Categories` (`PrsCatID`),
ADD CONSTRAINT `Persons_PersonCategories_ibfk_7` FOREIGN KEY (`PersonID`) REFERENCES `Persons` (`PersonID`);
Persons_PersonCateogires是n:m关系的链接表。当我尝试通过我的php应用程序将PersonID和PrsCatID插入Persons_PersonCategories时,我收到以下错误:
插入期间发生错误:
无法添加或更新子行:外键约束失败 (
ubarry09_andrew/Persons_PersonCategories
,CONSTRAINTPersons_PersonCategories_ibfk_7
FOREIGN KEY(PersonID
)参考Persons
(PersonID
))
这是插入语句:
INSERT INTO Persons_PersonCategories
VALUES (PersonID, PrsCatID)
Persons和Persons_Categories表填充了数据。
非常感谢,zan
答案 0 :(得分:3)
以下SQL语句是合法的,但它可能不符合您的意图:
INSERT INTO Persons_PersonCategories
VALUES (PersonID, PrsCatID);
这基本上尝试插入(NULL, NULL)
,因为它在创建行之前评估VALUES
子句中的表达式。但是表达式在尚未创建的行的上下文中命名列,因此没有值可供使用。因此它对两者都使用NULL。
PRIMARY KEY列中不允许使用NULL,当您将它们用于主键列时,MySQL会自动提升NULL值。在这种情况下,它将它们提升为整数值0.Persons和PersonCategories表中没有值0,因此您得到FK错误。
尝试此实验:
CREATE TABLE IF NOT EXISTS `Persons_PersonCategories2` (
`PersonID` int(11) NOT NULL,
`PrsCatID` int(11) NOT NULL,
PRIMARY KEY (`PersonID`,`PrsCatID`),
KEY `PrsCatID` (`PrsCatID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
也就是说,一个像您创建的表,但没有FK约束。
INSERT INTO Persons_PersonCategories2
VALUES (PersonID, PrsCatID);
SELECT * FROM Persons_PersonCategories2;
+----------+----------+
| PersonID | PrsCatID |
+----------+----------+
| 0 | 0 |
+----------+----------+
当您尝试在父级的引用PK列中不存在的FK列中插入值时,会出现外键约束错误。零通常不会被自动增量主键使用,因此它必然会失败。
您需要做的是为此INSERT提供您要引用的相应表中的主要值。像这样:
$stmt = $pdo->prepare("INSERT INTO Persons_PersonCategories (PersonID, PrsCatID)
VALUES (?, ?)");
使用prepared statements很简单,它有助于防止SQL注入错误。然后在执行时从其他表中提供值。这些值自动绑定到您在准备好的查询中使用的?
占位符:
$stmt->execute( array(1234, 5678) );
只要这些值1234和5678对应于引用的表Persons和PersonCategories中的现有行,就会满足外键约束。
答案 1 :(得分:2)
看起来您在Persons_PersonCategories表上设置了一个FOREIGN KEY约束,该约束不允许您将任何PersonID添加到Persons表中尚不存在的Persons_PersonCategories表中。您的Persons_PersonCategories表上还有另一个FOREIGN KEY,它只允许您添加Person_Categories表中已存在的PrsCatID。好像你试图将PersonID添加到Persons表中不存在的Persons_Categories表中。
在尝试将记录添加到Persons_PersonCategories表之前,请确保您要添加到Persons_PersonCategories表中的PersonID存在于Persons表中。将PrsCatID添加到此表也是如此;首先确保Person_Category表中存在PrsCatID。如果您不希望Persons_PersonCategories表阻止您插入Persons和Person_Category表中尚不存在的值,则必须删除FOREIGN KEYS(或代码示例中显示的CONSTRAINT)。要删除CONSTRAINT,请使用以下行:
ALTER TABLE [TABLE_NAME] DROP FOREIGN KEY [CONSTRAINT_NAME]