简体   繁体   English

外键约束失败

[英]foreign key constraint fails

I have the following tables: 我有以下表格:

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 is a linking table for an:m relationship. Persons_PersonCateogires是:m关系的链接表。 When I try to insert PersonID and PrsCatID into the Persons_PersonCategories via my php application I get the following error: 当我尝试通过PHP应用程序将PersonID和PrsCatID插入Persons_PersonCategories时,出现以下错误:

An error occurs during insert: 插入期间发生错误:

Cannot add or update a child row: a foreign key constraint fails ( ubarry09_andrew/Persons_PersonCategories , CONSTRAINT Persons_PersonCategories_ibfk_7 FOREIGN KEY ( PersonID ) REFERENCES Persons ( PersonID )) 无法添加或更新子行:外键约束失败( ubarry09_andrew/Persons_PersonCategories ,CONSTRAINT Persons_PersonCategories_ibfk_7键( PersonID )参考PersonsPersonID ))

Here is the insert statement: 这是插入语句:

INSERT INTO Persons_PersonCategories
VALUES (PersonID, PrsCatID)

Persons and Persons_Categories tables are populated with data. Persons和Persons_Categories表填充有数据。

Many thanks, zan 非常感谢,赞

The following SQL statement is legal, but it probably doesn't do what you intend: 以下SQL语句是合法的,但可能无法满足您的期望:

INSERT INTO Persons_PersonCategories
VALUES (PersonID, PrsCatID);

This basically tries to insert (NULL, NULL) because it evaluates the expressions in the VALUES clause before it creates the row. 这基本上是尝试插入(NULL, NULL)因为它在创建行之前先对VALUES子句中的表达式进行求VALUES But the expressions name columns within the context of the yet-to-be-created row, so there are no values to use. 但是表达式在尚未创建的行的上下文中命名列,因此没有要使用的值。 Thus it uses NULL for both. 因此,两者都使用NULL。

NULLs are not allowed in PRIMARY KEY columns, and MySQL automatically promotes NULL values when you use them for primary key columns. 在PRIMARY KEY列中不允许使用NULL,当您将NULL值用于主键列时,MySQL会自动提升NULL值。 In this case it promotes them to the integer value 0. There is no value 0 in the Persons and PersonCategories tables, so you get an FK error. 在这种情况下,它将它们提升为整数值0。Persons和PersonCategories表中没有值0,因此会出现FK错误。

Try this experiment: 试试这个实验:

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;

That is, a table like the one you created, but with no FK constraints. 也就是说,与您创建的表类似,但没有FK约束。

INSERT INTO Persons_PersonCategories2
VALUES (PersonID, PrsCatID);

SELECT * FROM Persons_PersonCategories2;
+----------+----------+
| PersonID | PrsCatID |
+----------+----------+
|        0 |        0 |
+----------+----------+

You get foreign key constraint errors when you try to insert a value in an FK column that doesn't exist in the referenced PK column of the parent. 当您尝试在父项的引用PK列中不存在的FK列中插入值时,会出现外键约束错误。 Zero is typically not used by auto-increment primary keys, so it's bound to fail. 自动增量主键通常不使用零,因此它肯定会失败。

What you need to do is provide this INSERT with the primary values from the respective tables you want to reference. 您需要做的是为此INSERT提供您要引用的各个表中的主要值。 Like this: 像这样:

$stmt = $pdo->prepare("INSERT INTO Persons_PersonCategories (PersonID, PrsCatID) 
    VALUES (?, ?)");

Using prepared statements is easy and it helps to protect against SQL injection mistakes. 使用准备好的语句很容易,并且有助于防止SQL注入错误。 Then supply values from the other tables when you execute. 然后在执行时提供其他表中的值。 These values are automatically bound to the ? 这些值自动绑定到? placeholders you used in the prepared query: 您在准备好的查询中使用的占位符:

$stmt->execute( array(1234, 5678) );

As long as those values 1234 and 5678 correspond to existing rows in your referenced tables Persons and PersonCategories, the foreign key constraint will be satisfied. 只要那些值1234和5678对应于您引用的表Persons和PersonCategories中的现有行,就将满足外键约束。

It looks like you have a FOREIGN KEY constraint set on the Persons_PersonCategories table that is not allowing you to add any PersonID to the Persons_PersonCategories table that doesn't already exist in the Persons table. 看来您在Persons_PersonCategories表上设置了FOREIGN KEY约束,该约束不允许您将任何PersonID添加到Persons表中尚不存在的Persons_PersonCategories表中。 You also have another FOREIGN KEY on your Persons_PersonCategories table that only allows you to add a PrsCatID that already exists in the Person_Categories table. 您的Persons_PersonCategories表上还有另一个FOREIGN KEY,仅允许您添加Person_Categories表中已经存在的PrsCatID。 It seems as though you are trying to add a PersonID to the Persons_Categories table that does not exist in the Persons table. 似乎您正在尝试将PersonID添加到Persons表中不存在的Persons_Categories表中。

Make sure the PersonID you are adding to the Persons_PersonCategories table exists in the Persons table before you try to add the record to the Persons_PersonCategories table. 在尝试将记录添加到Persons_PersonCategories表之前,请确保Person表中存在要添加到Persons_PersonCategories表中的PersonID。 The same thing goes for adding a PrsCatID to this table; 向此表添加PrsCatID也是一样。 first make sure the PrsCatID exists in the Person_Category table. 首先,确保Person_Category表中存在PrsCatID。 If you don't want the Persons_PersonCategories table to prevent you from inserting values that don't already exist in the Persons and Person_Category tables, then you will have to remove the FOREIGN KEYS (or CONSTRAINTs as they are shown in your code example). 如果您不希望Persons_PersonCategories表阻止您插入Persons和Person_Category表中尚不存在的值,那么您将必须删除FOREIGN KEYS(或CONSTRAINT,如代码示例中所示)。 To remove the CONSTRAINTs use the following line: 要删除约束,请使用以下行:

ALTER TABLE [TABLE_NAME] DROP FOREIGN KEY [CONSTRAINT_NAME]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM