我想用一个更新查询来更新多行。我可以不用这样的绑定来做到这一点:
Product::whereIn('id',[1,2,3])->update([
'stock' => DB::raw('CASE id WHEN 1 THEN 1000 WHEN 2 THEN 1001 WHEN 3 THEN 1003 END')
]);
但是,我想对CASE语句使用数据绑定。我已经尝试过:
Product::whereIn('id',[1,2,3])->setBindings([1,1,2,2,3,3])->update([
'stock' => DB::raw('CASE id WHEN ? THEN ? WHEN ? THEN ? WHEN ? THEN ? END')
]);
Product::whereIn('id',[1,2,3])->update([
'stock' => DB::raw('CASE id WHEN ? THEN ? WHEN ? THEN ? WHEN ? THEN ? END')
])->setBindings([1,1,2,2,3,3]);
两者都会产生错误:
带有消息'SQLSTATE [HY093]的Illuminate / Database / QueryException:无效的参数号(SQL:
update `products` set `stock` = CASE id WHEN 2020-03-19 08:58:16 THEN 1 WHEN 2 THEN 3 WHEN ? THEN ? END, `products`.`updated_at` = ? where `id` in (?, ?, ?) and `products`.`deleted_at` is null)'
我也尝试过:
Product::whereIn('id',[1,2,3])->update([
'stock' => DB::raw('CASE id WHEN ? THEN ? WHEN ? THEN ? WHEN ? THEN ? END')
->setBindings([1,1,2,2,3,3])
]);
哪个会产生以下错误:
PHP错误:在第1行的Psy Shell代码中调用未定义的方法Illuminate / Database / Query / Expression :: setBindings()
更仔细地查看错误消息,我能够发现问题是,update语句中时间戳的默认绑定和whereIn子句的参数将覆盖我手动设置的绑定。我的解决方案是将whereIn子句切换到whereRaw并在update语句中包含updated_at:
Product::setBindings([1,1,2,2,3,3,1,2,3])->
whereRaw('`id` in (?, ?, ?)')->
update([
'stock' => DB::raw('case `id` WHEN ? THEN ? WHEN ? THEN ? WHEN ? THEN ? end'),
'updated_at' => DB::raw('now()'),
]);