我有以下表格:
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_PersonCategories是一个n:m关系的链接表。当我试图通过我的php应用程序将PersonID和PrsCatID插入Persons_PersonCategories时,我得到了以下错误:
插入过程中发生错误:
无法添加或更新子行:外键约束失败(
ubarry09_andrew/Persons_PersonCategories
,约束Persons_PersonCategories_ibfk_7
外键(PersonID
)引用Persons
(PersonID
))
以下是插入语句:
INSERT INTO Persons_PersonCategories
VALUES (PersonID, PrsCatID)
Persons和Persons_Categories表由数据填充。
非常感谢,zan
下面的SQL语句是合法的,但它可能不会达到您的目的:
INSERT INTO Persons_PersonCategories
VALUES (PersonID, PrsCatID);
这基本上是尝试插入(NULL, NULL)
,因为它在创建行之前计算VALUES
子句中的表达式。但是表达式在尚未创建的行的上下文中命名列,因此没有可使用的值。因此,它对两者都使用NULL。
PRIMARY KEY列中不允许NULL,当您将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 (?, ?)");
使用准备好的语句很容易,而且有助于防止SQL注入错误。然后在执行时提供其他表中的值。这些值会自动绑定到您在准备好的查询中使用的?
占位符:
$stmt->execute( array(1234, 5678) );
只要这些值1234和5678对应于您引用的表Persons和PersonCategories中的现有行,外键约束就会得到满足。
看起来您在Persons_PersonCategories表上设置了一个FOREIGN KEY约束,该约束不允许您向Persons_PersonCategories表中添加PersonID,而Persons表中还不存在该约束。您的Persons_PersonCategories表上还有另一个FOREIGN KEY,它只允许您添加Person_Categories表中已经存在的PrsCatID。您似乎正在尝试将PersonID添加到Persons_Categories表中,但Persons表中不存在该PersonID。
在尝试将记录添加到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]