You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent查询构建器嵌套Where与orWhereNull返回异常结果

问题:Laravel嵌套查询中where搭配orWhereNull返回不符合条件的结果

在使用Laravel查询构造器时,嵌套where闭包中结合where和orWhereNull出现异常:生成的SQL语句结构正确,直接执行该SQL仅返回1条符合条件的结果,但通过$query->get()获取的结果却包含2条记录,其中一条的origen_id既不等于指定值也不为null。

代码示例

$query = Document::where("active", true)->where("type_id", $document_type->id);
if($selected) {
    $query->where(function($q) use($selected) {
        return $q->where("origen_id", $selected->id)
            ->orWhereNull("origen_id");
    });
}
$result = $query->orderBy("origen_id")->get();

调试信息

  • $query->toSql()生成的SQL:
select * from documents where active = ? and type_id = ? and (origen_id = ? or origen_id is null)
  • 已确认查询绑定值完全正确。

排查方向与解决方案

  1. 检查全局作用域
    Laravel模型可能被附加了全局作用域,会自动修改所有查询条件。可以临时禁用全局作用域验证:
$result = $query->withoutGlobalScopes()->get();

如果结果恢复正常,说明是全局作用域干扰了原查询条件。

  1. 禁用关联预加载
    若Document模型设置了$with属性自动预加载关联,可能导致结果集展示异常。尝试禁用预加载:
$result = $query->setEagerLoads([])->get();
  1. 生成完整绑定SQL验证
    手动拼接绑定值生成完整SQL,在数据库客户端执行对比结果:
$rawSql = str_replace('?', "'%s'", $query->toSql());
$fullSql = vsprintf($rawSql, $query->getBindings());
dd($fullSql);

如果数据库执行该SQL的结果与get()结果不一致,说明Laravel查询构造器执行过程中存在额外修改;若一致,则需排查数据库层面的缓存或数据异常。

  1. 检查属性转换规则
    确认Document模型中origen_id的属性转换设置,若存在类型转换错误(如字符串转整数不匹配),会导致查询条件失效:
// 检查模型的$casts属性
protected $casts = [
    'origen_id' => 'integer', // 确认与数据库字段类型匹配
];
  1. 处理数据库空值逻辑
    部分数据库会将空字符串与NULL视为不同值,若origen_id存在空字符串的情况,需补充查询条件:
$query->where(function($q) use($selected) {
    return $q->where("origen_id", $selected->id)
        ->orWhereNull("origen_id")
        ->orWhere("origen_id", "");
});

内容的提问来源于stack exchange,提问作者Damián Cardona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:40:24