PDO UPDATE语句执行失败但INSERT正常,求问题排查解决方法
问题原因
- UPDATE语句的WHERE子句直接拼接PHP变量,未使用预处理占位符,易触发SQL语法错误,同时存在SQL注入风险。若
$id_ecole等变量为字符串类型,没有引号包裹会直接导致SQL执行失败。 - 若业务逻辑需要修改
id_ecole、id_classe、id_eleve三个字段的值,现有代码WHERE条件中使用的是修改后的新值,无法匹配到原有数据行,最终更新行数为0,无执行效果。 - 表存在自增主键的前提下,未使用主键作为WHERE匹配条件,联合键变更时容易出现匹配失效问题。
INSERT语句无WHERE条件,所有参数都通过预处理占位符传入,语法合法参数有效即可执行成功,因此不受上述问题影响。
修正方案
场景1:不需要修改id_ecole、id_classe、id_eleve三个字段
无需将这三个字段放入SET列表,直接用其作为匹配条件即可:
$conn = new PDO("mysql:host=$host;dbname=$db", $login, $mdp); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $requete=$conn->prepare("UPDATE eleves SET nom = ?, prenom = ?, date_naiss = ?, tel = ?, mail = ?, sortie = ?, photo = ?, cantine = ?, religion = ? WHERE id_ecole = ? AND id_classe = ? AND id_eleve = ?"); $requete->execute(array($nom, $prenom, $date_naiss, $tel, $mail, $sortie, $photo, $cantine, $religion, $id_ecole, $id_classe, $id_eleve)); // 可通过rowCount方法确认更新行数 var_dump($requete->rowCount());
场景2:需要修改id_ecole、id_classe、id_eleve三个字段
提前留存三个字段的旧值作为WHERE匹配条件:
$conn = new PDO("mysql:host=$host;dbname=$db", $login, $mdp); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $requete=$conn->prepare("UPDATE eleves SET id_ecole = ?, id_classe = ?, id_eleve = ?, nom = ?, prenom = ?, date_naiss = ?, tel = ?, mail = ?, sortie = ?, photo = ?, cantine = ?, religion = ? WHERE id_ecole = ? AND id_classe = ? AND id_eleve = ?"); $requete->execute(array($id_ecole, $id_classe, $id_eleve, $nom, $prenom, $date_naiss, $tel, $mail, $sortie, $photo, $cantine, $religion, $old_id_ecole, $old_id_classe, $old_id_eleve));
内容的提问来源于stack exchange,提问作者Evosub
相关产品推荐
相关产品推荐

