ON DELETE CASCADE在MariaDB生效但PHP PDO中失效问题求助
PDO执行DELETE时ON DELETE CASCADE未触发,仅删除主表记录
我需要删除plats表(主表)的一条记录,并通过外键的ON DELETE CASCADE规则同步删除plats_categories表(关联表)的匹配记录。直接在MariaDB中执行DELETE语句时,级联删除正常生效,两张表的对应记录都会被删除;但用PHP PDO的prepare和execute方法执行时,只有plats表的记录被删除,plats_categories的对应记录残留,造成数据库冗余。
表结构
-- 主表 plats CREATE TABLE plats( id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL, description VARCHAR(300) NOT NULL, price INTEGER NOT NULL) ENGINE=InnoDB; -- 分类表 category1 CREATE TABLE category1( c1_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, c1_type VARCHAR(255) NOT NULL) ENGINE=InnoDB; -- category2结构与category1一致 CREATE TABLE category2( c2_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, c2_type VARCHAR(255) NOT NULL) ENGINE=InnoDB; -- 关联表 plats_categories CREATE TABLE plats_categories( pc_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, plats_id INTEGER NOT NULL, category1_id INTEGER NOT NULL, category2_id INTEGER NOT NULL, FOREIGN KEY(plats_id) REFERENCES plats(id) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY(category1_id) REFERENCES category1(c1_id) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY(category2_id) REFERENCES category2(c2_id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
PHP模型代码(delete-course.php)
<?php require_once __DIR__ .'/../db.php'; $getIdCourse = $_GET['id']; $courses = $pdo->prepare('SELECT * FROM plats WHERE id = ?'); $courses->execute(array($getIdCourse)); if ($courses->rowCount() > 0) { $deleteCourse = $pdo->prepare('DELETE FROM plats WHERE id = ?'); $deleteCourse->execute(array($getIdCourse)); }else { $_SESSION['flash']['danger'] = 'Aucun plat n\'a été trouvé'; }
PHP控制器代码
<?php session_start(); if (isset($_GET['id']) && !empty($_GET['id'])) { require __DIR__ .'/../../../model/menus-carte/delete-course.php'; $_SESSION['flash']['success'] = 'Le plat a bien été supprimé'; header('Location: admin-courses.php'); }else { $_SESSION['flash']['danger'] = 'L\'identifiant du plat n\'a pas été récupéré'; }
可能的原因及解决方法
- 检查PDO自动提交设置:查看
db.php中的PDO连接配置,如果设置了PDO::ATTR_AUTOCOMMIT => false,删除操作后需要手动执行$pdo->commit();,级联操作才会触发。 - 验证外键约束有效性:执行
SHOW CREATE TABLE plats_categories;,确认plats_id的外键定义包含ON DELETE CASCADE,且表引擎为InnoDB(MyISAM不支持外键)。 - 开启PDO错误模式:在
db.php的PDO初始化代码中添加$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);,捕获隐藏的外键相关错误。 - 确认数据类型匹配:检查
plats.id和plats_categories.plats_id的数据类型完全一致(均为INTEGER),类型不匹配会导致外键约束失效。 - 排查事务冲突:如果代码其他地方开启了事务但未正确提交/回滚,会影响当前删除操作的级联执行,需检查相关事务逻辑。
内容的提问来源于stack exchange,提问作者MAX
相关产品推荐
相关产品推荐

