【问题标题】:Can't insert : A foreign key constraint fails无法插入:外键约束失败
【发布时间】:2016-06-04 02:51:38
【问题描述】:

我有以下表格:

CREATE TABLE IF NOT EXISTS `location`(
    `ID` int(11) NOT NULL,
    `name` varchar(25) NOT NULL,
    `water` varchar(25) NOT NULL,
    `fodder` varchar(25) NOT NULL,
    `access` varchar(25) NOT NULL,
    PRIMARY KEY  (`ID`)
    KEY `water` (`water`)
    KEY `fodder` (`fodder`)
    KEY `access` (`access`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;
CREATE TABLE IF NOT EXISTS `watercondition`(
    `ID` int(11) NOT NULL,
    `watervalue` varchar(25) NOT NULL,
    PRIMARY KEY  (`watervalue`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;
CREATE TABLE IF NOT EXISTS `foddercondition`(
    `ID` int(11) NOT NULL,
    `foddervalue` varchar(25) NOT NULL,
    PRIMARY KEY  (`foddervalue`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;
CREATE TABLE IF NOT EXISTS `accesscondition`(
    `ID` int(11) NOT NULL,
    `accessvalue` varchar(25) NOT NULL,
    PRIMARY KEY  (`accessvalue`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;

对于约束表:

ALTER TABLE `location`
    ADD CONSTRAINT `location_ibfk2` FOREIGN KEY (`water`) REFERENCES `watercondition` (`watervalue`),
    ADD CONSTRAINT `location_ibfk3` FOREIGN KEY (`fodder`) REFERENCES `foddercondition` (`foddervalue`),
    ADD CONSTRAINT `location_ibfk4` FOREIGN KEY (`access`) REFERENCES `accesscondition` (`accessvalue`);

在我的 php 文件中,我想向所有表中插入一个值,如下所示:

$sqlwater = "INSERT INTO  `watercondition` (`ID`, `watervalue`) VALUES ('".$_SESSION['loc_id']."', '$watervalue')";
$resultwater = mysqli_query($con, $sqlwater) or die (mysqli_error($con));

$sqlfodder = "INSERT INTO  `foddercondition` (`ID`, `foddervalue`) VALUES ('".$_SESSION['loc_id']."', '$foddervalue')";
$resultfodder = mysqli_query($con, $sqlfodder) or die (mysqli_error($con));

$sqlaccess = "INSERT INTO  `accesscondition` (`ID`, `accessvalue`) VALUES ('".$_SESSION['loc_id']."', '$accessvalue')";
$resultaccess = mysqli_query($con, $access) or die (mysqli_error($con));

$sqlloc = "INSERT INTO  `location` (`ID`, `name`) VALUES ('".$_SESSION['loc_id']."', '$name')";
$resultaccess = mysqli_query($con, $access) or die (mysqli_error($con));

但是当我执行 php 文件时,我得到了这个错误:

无法添加或更新子行:外键约束失败(mydb.location, CONSTRAINT location_ibfk2 FOREIGN KEY (water) REFERENCES watercondition (watervalue))

当我检查我的数据库时,waterfodderaccess 的值已经插入数据库,但不在我的 location 表中。

【问题讨论】:

  • 您没有在上次插入时插入 water(或 fodderlocation)的值。
  • 您创建了一个包含 3 个外键的表,然后尝试插入一条记录,该记录为这些外键中的 NONE 提供值,因此 mysql 非常正确地抱怨它。
  • 每次看到外键约束失败时,我都会默默感谢我的 DBMS 阻止我搞砸数据。

标签: php mysql database sql-insert foreign-key-relationship


【解决方案1】:

插入location 表还必须包含waterfodderlocation 列的值。它们是location 表中的列,不能被忽略。

另外,您在最终查询中使用了错误的查询变量。

我猜这里发生的情况是 MYSQL 在检查您是否拥有所有 NOT NULL 字段的值之前正在验证约束,因此您会在更明显的关于缺少列值的错误之前得到约束错误。

$sqlloc = "INSERT INTO  `location` 
           (`ID`, `name`, `water`, `fodder`, `location`) 
      VALUES ('{$_SESSION['loc_id']}', '$name', 
              '$watervalue', '$foddervalue', '$accessvalue' )";

$resultaccess = mysqli_query($con, $sqlloc) or die (mysqli_error($con));

【讨论】:

    【解决方案2】:

    你应该在你的位置表中插入外键来维护你之前创建的关系。

    您对位置的查询应该类似于

    `$sqlloc = "INSERT INTO  'location' ('ID', 'name', 'water', 'footer', 'access') VALUES ('".$_SESSION['loc_id']."', '$name', 'water-related-id', 'fodder-related-id, 'access-related-id)";`
    

    无论如何,一个表的主键应该是'id'列,外键应该是其他表的主键,所以你的约束应该是

    ALTER TABLE 'location'
        ADD CONSTRAINT 'location_ibfk2' FOREIGN KEY ('water') REFERENCES 'watercondition' ('id'),
        ADD CONSTRAINT 'location_ibfk3' FOREIGN KEY ('fodder') REFERENCES 'foddercondition' ('id'),
        ADD CONSTRAINT 'location_ibfk4' FOREIGN KEY ('access') REFERENCES 'accesscondition' ('id');
    

    而且,您的外键数据类型应该与引用表的键匹配,在您的情况下是 int(11)。


    你这样做是为了大学作业吗?

    【讨论】:

      【解决方案3】:

      改变你的最后一个插入语句,如下所示:

      "INSERT INTO  `location` (`ID`, `name`,`water`,`fodder`,`access`) VALUES 
       ('".$_SESSION['loc_id']."', '$name','$watervalue','$foddervalue','$accessvalue')";
      

      说明:

      ERD:

      看黄色标记的表是表,你的location表是子表。

      因此,根据 MySQL,您无法通过相应父表中不存在的某些外键值添加或更新子表行 (location)。

      在您的前三个插入语句中,您正在更新您的三个父表,这很好。

      但在您的最终插入语句中,您正在尝试更新您的子表,其中您没有为那些外键提供任何值,这是一个异常

      SQL FIDDLE

      Reference

      【讨论】:

      • 你收到了吗@aureliadsp
      【解决方案4】:

      这里要注意两点:

      首先,您的插入不起作用,因为您将所有外键都设置为“NOT NULL”字段,因此当您在位置表上插入记录时,您必须提供这些值。

      其次,您必须确保作为外键的字段在原始表上具有相同的数据类型。在您的代码中,您在原始表上使用 INT(11) id 字段,但在位置表上使用 VARCHAR(25) 并且您链接到保存值的字段而不是链接到主键 (id) 字段引用表。

      亲切的问候, 丹尼尔

      【讨论】:

      • 我可能在这里遗漏了一些东西,但是他在哪里为每个查询连接和断开连接?
      • 我也看不到它@andrewsi 实际上除了第一段之外它都错了
      • 对不起,我又看了一遍代码,确实连接有问题。
      猜你喜欢
      • 2016-07-08
      • 1970-01-01
      • 2011-10-04
      • 2012-06-21
      • 2013-05-29
      • 1970-01-01
      • 2019-03-23
      • 2015-04-24
      • 1970-01-01
      相关资源
      最近更新 更多