Laravel不执行带有“having”子句的查询。

3

我手动使用各种Eloquent函数(即$this->newQuery()->join...)构建了一个大查询,但无法运行。

当我调用时

echo $query->toSql();

它展示给我查询语句。我可以将其复制粘贴到我的命令行mysql客户端中,并且它可以正常运行并返回多行结果。但是当我调用

echo $query->count();

或者

echo $query->get()->count();

显示为0。

最终,我启用了MySQL的常规日志来查看发生了什么。我发现当Laravel运行时,它会执行多个查询-每个查询在日志中都有一行prepare,接着是一行execute。但是这个查询没有。

似乎Laravel正在准备语句,但从未执行。为什么呢?

经过多次测试,我已经确定了导致问题的代码行:

$query->having('book_author_author_id', 'NOT IN', DB::raw('('.implode(',',$author_ids).')'));

看起来,包含“having”子句的查询不会被 Laravel 执行,相反它会假装执行并返回一个空集合。发生了什么?

2个回答

2
问题在于laravel无法正确解析having子句中的DB::raw语句。由于它也不允许通过数组传递,这实际上使得使用having x in (1,2,3)编写查询变得不可能。解决方法是使用多个单独的having子句。因此,在这种情况下,应该像这样编写:
foreach($author_ids as $id) {
    $query->having('book_author_author_id', '!=', $id);
}

又是一个令人烦恼的例子,展示了Eloquent功能的限制。

0

试试这个:

$query->havingRaw(
  "{book_author_author_id} IN ('". implode("','", $author_ids) . "')"
);

虽然这段代码可能回答了问题,但提供关于为什么和/或如何回答问题的额外上下文可以提高其长期价值。 - Justin Howard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接