duanli9591 2012-01-23 18:28
浏览 60
已采纳

外键约束失败

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 a n:m relationship. When I try to insert PersonID and PrsCatID into the Persons_PersonCategories via my php application I get the following error:

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))

Here is the insert statement:

INSERT INTO Persons_PersonCategories
VALUES (PersonID, PrsCatID)

Persons and Persons_Categories tables are populated with data.

Many thanks, zan

  • 写回答

2条回答 默认 最新

  • dsgoj7457 2012-01-23 19:20
    关注

    The following SQL statement is legal, but it probably doesn't do what you intend:

    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. 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.

    NULLs are not allowed in PRIMARY KEY columns, and MySQL automatically promotes NULL values when you use them for primary key columns. 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.

    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.

    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. 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. 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. 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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100