无法插入:外键约束失败

Can't insert : A foreign key constraint fails

我有以下 tables:

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 ;

并且对于约束 table :

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 文件中,我想像这样向所有 table 插入一个值:

$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 文件时,我得到这个错误:

Cannot add or update a child row: a foreign key constraint fails (mydb.location, CONSTRAINT location_ibfk2 FOREIGN KEY (water) REFERENCES watercondition (watervalue))

当我检查我的数据库时,来自 waterfodderaccess 的值已经插入数据库,但不在我的 location table.

这里需要注意两点:

首先,您的插入无效,因为您创建了所有外键 "NOT NULL" 字段,因此当您在 table 位置插入记录时,您必须提供这些值。

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

的主键 (id) 字段

亲切的问候, 丹尼尔

像下面这样更改您的最后一个插入语句:

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

解释:

ERD:

看黄色标记的 table 是 parent table 和你的 location table是 child table.

因此,根据 MySQL,您不能通过某些不存在于相应 parent table(s).

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

但是在你最后的插入语句中你试图更新你的 child table 你没有为那些外键提供任何值这是一个 exception.

SQL FIDDLE

Reference

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

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

我想这里发生的事情是 MYSQL 在检查您是否具有所有 NOT NULL 字段的值之前正在验证约束,因此您在 more关于缺失列值的明显问题。

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

您应该在您的位置插入外键 table 以维护您之前创建的关系。

您的位置查询应该像

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

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

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

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


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