Laravel Eloquent版本更新后查询SQL逻辑异常求助
Laravel升级后orWhere数组条件异常的解决办法
问题背景
之前用这段代码查询库存交易记录:
$where = [ ['warehouse_id', $warehouse->id], ['product_id', $product->id], ['section_id', $sectionId] ]; $orWhere = [ ['to_warehouse_id', $warehouse->id], ['product_id', $product->id], ['section_id', $sectionId] ]; $transactions = InventoryTransaction::where($where)->orWhere($orWhere)->get();
旧版本生成的SQL符合预期,两组条件分别用AND组合后再进行OR判断:
select * from `inventory_transactions` where ((`warehouse_id` = ? and `product_id` = ? and `section_id` = ?) or (`to_warehouse_id` = ? and `product_id` = ? and `section_id` = ?)) and `inventory_transactions`.`deleted_at` is null
但执行composer update后,原代码生成的SQL逻辑发生变化,orWhere里的条件变成了OR关系:
select * from `inventory_transactions` where ((`warehouse_id` = ? and `product_id` = ? and `section_id` = ?) or (`to_warehouse_id` = ? or `product_id` = ? or `section_id` = ?)) and `inventory_transactions`.`deleted_at` is null
这导致查询出大量重复数据,只能改成两次查询再合并的方式:
$transactions = InventoryTransaction::where($where)->get(); $t = InventoryTransaction::where($orWhere)->get(); $transactions = $transactions->merge($t);
但需要修改的代码量太大,无法顺利完成版本升级。
解决办法
把orWhere的数组条件用闭包包裹,确保内部条件始终保持AND组合:
$where = [ ['warehouse_id', $warehouse->id], ['product_id', $product->id], ['section_id', $sectionId] ]; $orWhere = [ ['to_warehouse_id', $warehouse->id], ['product_id', $product->id], ['section_id', $sectionId] ]; $transactions = InventoryTransaction::where($where) ->orWhere(function($query) use ($orWhere) { $query->where($orWhere); }) ->get();
这样生成的SQL会和旧版本完全一致,既不用大面积修改代码,也能正常完成composer update升级。
原因说明
新版本Laravel调整了orWhere直接接收数组的逻辑:原本数组内的条件默认是AND组合,现在变成了OR组合。用闭包包裹后,内部的where($orWhere)依然保持多个条件的AND关系,再整体作为OR判断的一部分,完美还原旧版本的行为逻辑。
内容的提问来源于stack exchange,提问作者Hilal Najem
相关产品推荐
相关产品推荐

