简体   繁体   English

无法插入:外键约束失败

[英]Can't insert : A foreign key constraint fails

I have the following 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 ;

And for constraints 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`);

In my php file, i want to insert a value to all of the table like this : 在我的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));

But when I execute the php file, I get this error : 但是当我执行php文件时,出现此错误:

Cannot add or update a child row: a foreign key constraint fails ( mydb . location , CONSTRAINT location_ibfk2 FOREIGN KEY ( water ) REFERENCES watercondition ( watervalue )) 不能添加或更新子行,外键约束失败( mydblocation ,约束location_ibfk2外键( water )参考waterconditionwatervalue ))

When I check on my db, the value from water , fodder , and access have already been inserted db, but not in my location table. 当我检查数据库时, waterfodderaccess的值已经插入db了,但是不在我的location表中。

The insert into the location table must also include values for the water , fodder and location columns. location表中的插入内容还必须包括waterfodderlocation列的值。 They are columns in the location table and cannot just be ignored. 它们是location表中的列,不能被忽略。

Also you were using the wrong query variable in the final query. 另外,您在最终查询中使用了错误的查询变量。

I guess what is happening here is that the constraints are being validated by MYSQL before it checks that you have values for all the NOT NULL fields, so you get the constraint error before the more obvious one about missing column values. 我猜这里正在发生的事情是,在检查所有的NOT NULL字段的值之前,MYSQL已对约束进行了验证,因此在出现关于缺少列值的更为明显的约束之前,您会遇到约束错误。

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

Change your last insert statement like below: 更改您的最后一个插入语句,如下所示:

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

Explanation: 说明:

ERD: ERD:

在此处输入图片说明

Look the yellow marked tables are the parent tables and your location table is child table. 看起来黄色标记的表是表,而location表是子表。

So according to MySQL you cannot add or update a child table row ( location ) by some foreign key values which don't exist in corresponding parent table(s). 因此,根据MySQL,您无法通过相应的父表中不存在的某些外键值来添加或更新子表行( location )。

In your first three insert statements you are updating your three parent tables which is fine. 在前三个插入语句中,您将更新三个父表,这很好。

But in your final insert statement you are trying to update your child table where you provide with no values for those foreign keys which is an exception . 但是在您的最终插入语句中,您试图更新子表,在该表中您没有提供那些外键的值,这是一个例外

SQL FIDDLE SQL字段

Reference 参考

You should insert foreign key to your location table to maintain relation you have created before. 您应该将外键插入到位置表中,以保持之前创建的关系。

Your query for location should be like 您对位置的查询应类似于

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

Anyway, primary key for a table should be 'id' column and foreign key should be other table's primary key, so your constraints should be 无论如何,表的主键应为“ 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');

And, your foreign key data type should match referenced table's key which in your case is int(11). 并且,您的外键数据类型应与引用表的键匹配,在您的情况下为int(11)。


Are you doing this for college assignment? 你是在做大学作业吗?

Twothings to note here: 这里要注意的两点:

First of all, your insert is not working because you made all the foreign keys "NOT NULL" fields, so when you insert a record on the location table you must provide those values. 首先,插入操作无效,因为您将所有外键都设置为“ NOT NULL”字段,因此在位置表上插入记录时,必须提供这些值。

Second, you must make sure the fields that are foreign keys has the same data type on the original table. 其次,必须确保作为外键的字段在原始表上具有相同的数据类型。 In your code you are using INT(11) id fields on the original tables but are using VARCHAR(25) on the location table and you are linking to the field holding the value instead of linking to the primary key (id) field of the referenced table. 在您的代码中,您正在原始表上使用INT(11)id字段,但在位置表上使用了VARCHAR(25),并且您链接到保存该值的字段,而不是链接到该字段的主键(id)字段参考表。

Kind regards, Daniel 亲切的问候,丹尼尔

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

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