我们有一个用Laravel 5.2编写的旧应用程序。我们目前正在尝试升级到5.4,而我们最后一件事就是在哪里有一个bug。 以下是原始sql查询:
# Laravel 5.4 Query:
select * from `jobs` where exists (select * from `channels` where `jobs`.`channel_id` = `channels`.`id` OR (`id` = 'RetroSnickers' or `channelid` like 'RetroSnickers' or `channelname` like 'RetroSnickers' or exists (select * from `users` where `channels`.`user_id` = `users`.`id` and (`email` like 'RetroSnickers' or `full_name` like 'RetroSnickers')))) and `jobs`.`deleted_at` is null limit 24 offset 0
# Laravel 5.2 Query:
select * from `jobs` where exists (select * from `channels` where `jobs`.`channel_id` = `channels`.`id` AND (`id` = 'RetroSnickers' or `channelid` like 'RetroSnickers' or `channelname` like 'RetroSnickers' or exists (select * from `users` where `channels`.`user_id` = `users`.`id` and (`email` like 'RetroSnickers' or `full_name` like 'RetroSnickers')))) and `jobs`.`deleted_at` is null limit 24 offset 0
这是生成此原始sql的代码。我们的5.4版本中的代码与5.2版本中的代码相同:
$this->query->whereHas('channel', function(Builder $query) use ($search) {
$query->orWhere('id', '=', $search);
$query->orWhere('channelid', 'like', '%'.$search.'%');
$query->orWhere('channelname', 'like', '%'.$search.'%');
$query->orWhereHas('user', function(Builder $subQuery) use ($search) {
$subQuery->where(function(Builder $subQuery2) use ($search) {
$subQuery2->orWhere('email', 'like', '%'.$search.'%');
$subQuery2->orWhere('full_name', 'like', '%'.$search.'%');
});
});
});
原始sql的唯一区别是粗体,但基本上是mysql OR与AND之间的差异。 OR子句在5.4
中生成知道为什么吗?
答案 0 :(得分:3)
这是Laravel 5.3中发生的变化。来自5.3 upgrade guide:
Eloquent范围现在尊重范围约束的主要布尔值。例如,如果您使用orWhere约束启动范围,则将不再将其转换为normal。如果您依赖于此功能(例如,在循环中添加多个或者约束),则应验证第一个条件是否正常,以避免任何布尔逻辑问题。
在5.2中,如果你的第一个条件是orWhere()
,那么它会忽略' OR'部分和' AND'它与其他条件。从5.3开始,它尊重“OR”。部分和意志'或者'其余条件的第一个条件。
如果您需要' AND',则需要将第一个条件从orWhere()
更改为where()
:
$query->where('id', '=', $search);