Yii2中更新语句设fc_dore_reg.pay_all=1成功却报SQLSTATE[HY000]错误
Yii2更新成功却抛出SQLSTATE[HY000]: General Error的原因分析
这种情况我之前也碰到过好几次——明明数据库里的fc_dore_reg.pay_all已经被成功设为1了,但代码层面却抛出这个通用SQL错误。其实这通常不是更新操作本身的问题,而是你执行查询的方式或者后续操作出了纰漏,下面给你列几个最常见的诱因:
错误使用了查询类方法执行写操作
Yii2里,更新、删除这类写操作必须用execute()方法来执行,它会返回受影响的行数。如果你不小心用了one()、all()这类用来获取查询结果集的方法,就会报错——因为UPDATE语句本身不会返回结果集,只有受影响行数。比如下面的错误写法:// 错误:用one()去执行更新语句,会抛出General Error $result = Yii::$app->db->createCommand("UPDATE fc_dore_reg SET pay_all=1 WHERE id=:id", [':id' => 1])->one(); // 正确:用execute()执行写操作 $affectedRows = Yii::$app->db->createCommand("UPDATE fc_dore_reg SET pay_all=1 WHERE id=:id", [':id' => 1])->execute();这是最常见的原因,大概率你是踩了这个坑。
事务处理逻辑有漏洞
如果你的更新操作是在事务中执行的,可能后续的代码触发了异常导致事务回滚,但更新操作本身已经被数据库执行(不过正常来说事务回滚会撤销更新,除非你的事务配置有问题,比如数据库的自动提交没关)。或者你在事务中执行更新后,错误地调用了查询方法,导致抛出通用错误。比如:$transaction = Yii::$app->db->beginTransaction(); try { Yii::$app->db->createCommand("UPDATE fc_dore_reg SET pay_all=1 WHERE id=:id", [':id' => 1])->execute(); // 这里如果有错误的查询操作,会触发异常 Yii::$app->db->createCommand("SELECT * FROM non_existent_table")->queryAll(); $transaction->commit(); } catch (\Exception $e) { $transaction->rollBack(); throw $e; // 抛出的错误可能让你误以为是更新出了问题 }ActiveRecord的错误用法
如果你用ActiveRecord来更新数据,比如:$model = FcDoreReg::findOne($id); $model->pay_all = 1; // 错误:不要在save前/后调用查询类方法 $model->find(); // 正确:用save()完成更新 $model->save(false); // 若不需要验证可以传false错误地调用查询方法会让ActiveRecord试图去获取结果集,从而抛出通用错误。
数据库驱动或连接的小概率问题
比如PDO驱动的错误模式配置不正确,或者更新后数据库连接意外断开,但这种情况非常少见,优先排查前面的代码问题。
总的来说,先检查你执行更新语句的方法是不是用了execute(),而不是one()/all()这类查询方法,这解决了90%以上的类似问题。
内容的提问来源于stack exchange,提问作者Mohammad Aghayari
相关产品推荐
相关产品推荐

