最稳妥的是用createCommand()->update(),参数依次为表名、更新字段键值对、WHERE条件(推荐数组形式防注入);不传第三参数会全表更新,极其危险。

直接用 createCommand()->update() 最稳妥,比拼接原生 SQL 安全、简洁、可维护。
update() 方法的参数结构怎么填
Yii2 的 update() 是封装好的安全接口,三个参数依次是:表名、要更新的字段键值对、WHERE 条件(支持数组或字符串)。
- 条件用数组最推荐:
['id' => 123]自动转为WHERE id = 123,防 SQL 注入 - 条件用字符串需手动转义,比如
'status = 1 AND updated_at ,再配合 <code>bindValue()绑定变量 - 更新字段值支持表达式,如
['view_count' => new \yii\db\Expression('view_count + 1')] - 不传第三个参数会全表更新,等价于
UPDATE table SET ...—— 极其危险,务必确认
为什么别直接拼 SQL 字符串执行 update
手写 "UPDATE user SET name='xxx' WHERE id=$id" 看似简单,但实际埋雷:
-
$id若来自用户输入且未过滤,直接导致 SQL 注入(例如传入123 OR 1=1) - 字符串字段含单引号(如
O'Reilly)会导致语法错误,需手动addslashes或mysql_real_escape_string,易漏 - 日期、NULL、布尔值等类型在不同数据库中写法不一致,
update()内部自动适配 - 无法复用 Yii2 的日志、事务、重试等基础设施
带事务的批量更新怎么写
多个表联动更新必须加事务,否则中间失败会导致数据不一致:
$db = Yii::$app->db;
$transaction = $db->beginTransaction();
try {
$db->createCommand()->update('order', ['status' => 'shipped'], ['id' => $orderId])->execute();
$db->createCommand()->update('inventory', ['stock' => new \yii\db\Expression('stock - 1')], ['sku' => $sku])->execute();
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollBack();
throw $e;
}- 注意两个
update()调用都必须在try块内 - 不要在
execute()后加分号再换行,容易误删导致语法错误 - 事务内避免调用非 DB 操作(如发邮件、写文件),防止回滚失效
更新后怎么拿到影响行数或自增 ID
update() 返回的是影响的行数(int),不是新 ID —— 更新操作本身不产生新 ID:
- 返回
0表示没匹配到任何记录(WHERE 条件不成立),不是错误,需业务层判断 - 想确认是否真改了数据,建议先
SELECT旧值,或用updateAllCounters()做原子计数器 - 如果需要更新并返回某字段(如时间戳),得用两步:
update()+createCommand("SELECT updated_at FROM ...")->queryScalar()
真正容易被忽略的是条件为空时的默认行为——update('user', ['name'=>'a']) 不报错,但会静默更新全表。线上环境务必确保 WHERE 条件存在且有效。


















