外键配置双CASCADE可删父行但更新主键报1451错误求助
已尝试所有可检索到的相关解决方案,均未解决问题。
核心操作需求:更新classroom表的主键code_class,该字段同时是reservation表的外键关联字段。执行更新操作时持续返回如下报错:
Warning: PDOStatement::execute(): SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (
ebooking.reservation, CONSTRAINTreservation_ibfk_3FOREIGN KEY (code_class) REFERENCESclassroom(code_class) ON DELETE CASCADE ON UPDATE CASCADE) in C:\wamp64\www\last\ebooking2\profile\admin\updateClass.php on line 38
异常矛盾点:对同一条code_class记录执行删除操作可正常生效,按照报错信息标注,该外键确实同时配置了ON DELETE CASCADE与ON UPDATE CASCADE规则。
班级更新逻辑PHP代码
$requete = $bdd->prepare('SELECT * FROM classroom Where code_class = :C '); $requete->execute(array('C'=> $CR)); while ($donnees = $requete->fetch()){ if (isset($_POST) & !empty($_POST)) { $data = [ 'name' => $_POST['Code'], 'surname' => $_POST['STIME'], 'floor' => $_POST['fTIME'], 'roomtp' => $_POST['ETIME'], 'hard'=> $_POST['HARD'], 'id' => $CR, ]; $sql = "UPDATE classroom SET code_class=:name,capacity=:surname,floor=:floor,room_type=:roomtp, hardware_type=:hard WHERE code_class=:id "; $stmt= $bdd->prepare($sql); $stmt->execute($data); // echo "<script>window.location.assign('hardware.php')</script>"; }
班级删除逻辑PHP代码
<?php // error_reporting(0); session_start(); include('../../connexionDB.php'); if(!isset($_SESSION['CR']) ||$_SESSION['CR'] == ""){ echo 'no id found'; }else { $AS = $_SESSION['CR']; } echo $AS; $sql = "DELETE FROM `classroom` WHERE code_class =:c "; $statement = $bdd->prepare($sql); $statement->bindParam('c', $AS); // execute the statement if ($statement->execute()) { echo 'publisher id was deleted successfully.'; } ?>
外键创建SQL语句
ALTER TABLE `reservation` ADD FOREIGN KEY (`code_class`) REFERENCES `classroom`(`code_class`) ON DELETE CASCADE ON UPDATE CASCADE;
核心故障原因
删除操作可正常触发级联规则,说明你当前看到的reservation_ibfk_3外键的DELETE CASCADE逻辑正常,但UPDATE CASCADE未生效,根因是reservation表上存在冗余外键约束:
之前创建过同字段关联、未配置ON UPDATE CASCADE规则的外键,后续执行ADD FOREIGN KEY语句时MySQL不会覆盖旧约束,而是新增约束。更新主键时,未配置级联更新的旧约束先触发校验,直接抛出1451错误。
验证方法
执行SQL语句SHOW CREATE TABLE reservation;,查看返回的表结构定义,你会发现reservation表上不止一个关联code_class指向classroom表的外键,其中至少有一个外键未配置ON UPDATE CASCADE规则。
修复步骤
- 清理冗余外键:把
reservation表上所有关联code_class指向classroom表的外键全部删除,参考语句:ALTER TABLE reservation DROP FOREIGN KEY reservation_ibfk_3;,如果查到其他同关联的外键,按相同语法一并删除。 - 重建外键:重新执行你之前写的外键创建语句,确保表上只有一个配置了
ON DELETE CASCADE ON UPDATE CASCADE规则的关联外键。 - 修复代码逻辑bug:更新逻辑中判断表单提交的代码用了位运算符
&,需要替换为逻辑运算符&&,位运算在POST参数为空时会出现判断逻辑错误;同时更新主键前要校验$_POST['Code']的值,不能和classroom表现有code_class主键重复,主键重复也会触发约束报错。
内容的提问来源于stack exchange,提问作者Oumnia Rana SEGUENI

