【问题标题】:Laravel Query Builder returns no results while generated SQL works perfectLaravel 查询生成器在生成的 SQL 完美运行时不返回任何结果
【发布时间】:2020-02-25 23:59:39
【问题描述】:

我正在积极开展一个 laravel 项目,但遇到了一些查询构建器的问题。我试图避免使用 DB::Raw,但看起来我可能需要这样做。

        $query = app($this->model());
        $query = $query->select(['last_name', 'first_name', 'birthday'])
                       ->distinct()
                       ->leftJoin('enrollments', 'students_meta.uid', '=', 'enrollments.student_uid')

        ->whereIn('enrollments.type', $types)
        ->where('enrollments.startdate', '<=', "'{$today}'")
        ->where(function ($join) use ($today) {
            $join->where('enrollments.dropdate', '>=', "'{$today}'")
                  ->orWhereNull('enrollments.dropdate');
        });

        // todo: add viewBy filter
        $query = $query->where('birth_month', '=', Carbon::today()->month);
        $query = $query->orderBy('last_name')->orderBy('first_name');
        $models = $query->get();

上述查询生成器生成以下 SQL:

SELECT distinct `last_name`, `first_name`, `birthday` 
    FROM `students_meta` 
    LEFT JOIN `enrollments` ON `students_meta`.`uid` = `enrollments`.`student_uid` 
    WHERE `enrollments`.`type` IN ('ACTIVE', 'active') 
    AND `enrollments`.`startdate` <= '2019-10-29' 
    AND (`enrollments`.`dropdate` >= '2019-10-29' OR `enrollments`.`dropdate` IS NULL) 
    AND `birth_month` = 10 
ORDER BY `last_name` asc, `first_name` asc;

生成的 SQL 非常完美,基于我要迁移的旧代码,并产生了预期的结果。如果我移动一些东西,似乎我可以让查询生成器返回结果,但它们不是正确的。我查看了有关此类问题的其他问题/答案,并尝试了多种移动连接/更改位置的方案,但仍然没有运气。

有什么建议吗? (除了获取生成的 sql 并在 DB::Raw() 中运行它

【问题讨论】:

  • 从你的$today 那里去掉所有的引号,这可能把一切都搞砸了。使用查询生成器使用准备好的语句/参数,因此您的日期字符串类似于enrollments.dropdate &gt;= "'2019-10-29'"
  • 尝试调试结果查询:dd($query-&gt;toSql() 同时检查参数是否正常(主要是月份)
  • @aynber 我会检查的!我添加它们是因为对于 toSql(),它们需要在那里才能在实际的 sql 中正常工作。
  • @aynber 如果您提交正式答案,我会接受。这样做是因为 toSql() 是我进行这些更改的基础,但查询生成器不需要

标签: php laravel laravel-query-builder


【解决方案1】:
$query = $query->orderBy('last_name')->orderBy('first_name')->get();

您的查询运行良好,但您没有输出它。

您也可以使用-&gt;get()-&gt;toArray();来检索数组格式的数据

【讨论】:

  • 其实我忘了把get()行复制到这里,会更新
【解决方案2】:

$today 周围删除您的引号。 where 子句的第三个(或第二个,如果您消除比较运算符)参数将值作为参数发送到准备好的语句中。所以

 "'{$today}'"

在直接查询中看起来像这样:

where enrollments.startdate <= "'2019-10-29'"

所以将您的查询更改为

 ->where('enrollments.startdate', '<=', $today)

确保在查询中删除所有此类实例中的引号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 1970-01-01
    • 2018-08-05
    • 2021-09-12
    • 1970-01-01
    相关资源
    最近更新 更多