Yii2查询构建器实现字段更新与删除的方法咨询
Yii2中UPDATE/DELETE语句的正确实现方式
一、原生多语句执行失败的原因及解决
你用单条createCommand执行多条SQL失败,是因为Yii2默认禁用多语句执行(防止SQL注入风险)。正确做法是拆分语句单独执行:
// 执行第一条更新 Yii::$app->db->createCommand("UPDATE u4_portal.missed SET type='vacations' WHERE reason LIKE BINARY 'отпуск%'")->execute(); // 执行删除操作 Yii::$app->db->createCommand("DELETE FROM u4_portal.missed WHERE type = 'vacations'")->execute(); // 执行第三条更新 Yii::$app->db->createCommand("UPDATE u4_portal.missed SET type='absents'")->execute();
如果非要用多语句(不推荐,存在注入风险),可以在数据库配置中开启多语句支持:
// 配置文件里的db组件设置 'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=your_db', 'username' => 'root', 'password' => '', 'charset' => 'utf8', 'attributes' => [ PDO::MYSQL_ATTR_MULTI_STATEMENTS => true, ], ],
只有在你能100%确保SQL语句无风险时,再用这种方式。
二、转成Yii2查询构建器语法
查询构建器会自动处理参数转义,更安全也更易维护,对应转换如下:
1. 第一条UPDATE(带BINARY模糊匹配)
原生SQL:
UPDATE u4_portal.missed SET type='vacations' WHERE reason LIKE BINARY 'отпуск%';
查询构建器实现:
Yii::$app->db->createCommand() ->update('u4_portal.missed', ['type' => 'vacations'], 'reason LIKE BINARY :reason', [':reason' => 'отпуск%']) ->execute();
或者用表达式写法:
use yii\db\Expression; Yii::$app->db->createCommand() ->update('u4_portal.missed', ['type' => 'vacations'], ['like', new Expression('BINARY reason'), 'отпуск%', false]) ->execute();
2. DELETE语句
原生SQL:
DELETE FROM u4_portal.missed WHERE type = 'vacations';
查询构建器实现:
Yii::$app->db->createCommand() ->delete('u4_portal.missed', ['type' => 'vacations']) ->execute();
3. 全表UPDATE语句
原生SQL:
UPDATE u4_portal.missed SET type='absents';
查询构建器实现:
Yii::$app->db->createCommand() ->update('u4_portal.missed', ['type' => 'absents']) ->execute();
三、保证原子性:用事务包裹(可选)
如果这三条操作需要同时成功或失败,用事务包裹:
$transaction = Yii::$app->db->beginTransaction(); try { // 第一条更新 Yii::$app->db->createCommand() ->update('u4_portal.missed', ['type' => 'vacations'], 'reason LIKE BINARY :reason', [':reason' => 'отпуск%']) ->execute(); // 删除操作 Yii::$app->db->createCommand() ->delete('u4_portal.missed', ['type' => 'vacations']) ->execute(); // 第三条更新 Yii::$app->db->createCommand() ->update('u4_portal.missed', ['type' => 'absents']) ->execute(); $transaction->commit(); } catch (\Exception $e) { $transaction->rollBack(); throw $e; }
内容的提问来源于stack exchange,提问作者peanut_halva
相关产品推荐
相关产品推荐

