deleteall()仅返回受影响行数(int),不返回被删数据;需先查后删并加事务保障一致性,或用createcommand分步实现自定义返回。

Yii2 的 deleteAll() 方法本身不返回被删除的记录数据,只返回受影响的行数(int)。这是它和单条 delete() 的关键区别:它跳过模型实例化、不触发事件、不加载数据,直接执行 SQL DELETE,因此无法知道“删了哪些具体内容”,只能知道“删了几行”。
deleteAll() 的返回值含义
调用后得到的是一个整数,代表数据库中实际被删除的记录条数:
- 返回 0:条件没匹配到任何记录(安全,无误删)
- 返回 正整数(如 5):成功删除对应数量的行
- 返回 false:SQL 执行失败(如权限不足、连接中断),需配合异常捕获判断
如果业务需要知道“删了哪些数据”,得先查再删
不能依赖 deleteAll() 返回内容,必须分两步操作,并建议包裹事务:
- 用
select()或asArray()->all()先查出待删数据(可加锁:`forUpdate()`) - 记录 ID 列表或关键字段,用于日志、通知或后续处理
- 再调用
deleteAll()执行删除 - 事务中任一步失败,整体回滚
示例:
Yii::$app->db->transaction(function ($db) use ($plan_year_id, $allAdjustment, $is_auto) {
// 1. 先查
$toDelete = AllAdjustments::find()
->select(['id', 'column_type', 'column_id'])
->where([
'AND',
['plan_year_id' => $plan_year_id],
['column_type' => array_keys($allAdjustment)],
['is_auto' => $is_auto],
['NOT', ['column_id' => 1]],
])
->asArray()
->all();
// 记录日志或传递给其他服务
\Yii::info('即将删除 ' . count($toDelete) . ' 条记录', __METHOD__);
// 2. 再删
$affected = AllAdjustments::deleteAll([
'AND',
['plan_year_id' => $plan_year_id],
['column_type' => array_keys($allAdjustment)],
['is_auto' => $is_auto],
['NOT', ['column_id' => 1]],
]);
return $affected;
});
替代方案:用createCommand获取更底层控制
若需自定义返回(比如返回被删记录的 ID 列表),可用原生查询构造 SELECT + DELETE 组合逻辑,但 Yii2 不支持一条语句同时返回并删除。常见做法是:
- 用
createCommand("SELECT id FROM ...")查 ID 列表 - 用
createCommand("DELETE FROM ... WHERE id IN (:ids)")批量删(注意参数绑定限制,ID 过多需分批) - 手动组装返回结构(如
['deleted_ids' => $ids, 'count' => count($ids)])
注意事项
别试图从 deleteAll() 拿数据——它设计就是轻量、高效、无状态的。要审计、回溯或联动处理,必须前置查询。另外,永远对条件做严格校验,避免 deleteAll([]) 清空整表。











