Eloquent 查询只会准备,不会执行

Eloquent query will only prepare, not execute

这是给 Laravel 5.2 的。我的问题和this question. Basically, I'm trying to run a query that was suggested to me in another 非常相似,其中returns实际执行时的数据:

>>> App\Models\User::whereRaw('CONCAT(name_first, " ", name_last) LIKE "%?%"', ['test'])->get()
=> Illuminate\Database\Eloquent\Collection {#769
     all: [],
   }

这是 mysql 日志显示的内容:

Prepare   select * from `users` where CONCAT(name_first, " ", name_last) LIKE "%?%" and `users`.`deleted_at` is null
Close stmt

但是,这个语句有效:

>>> App\Models\User::whereRaw('CONCAT(name_first, " ", name_last) LIKE "%test%"')->get()
=> Illuminate\Database\Eloquent\Collection {#770
     all: [
       App\Models\User {#767
         id: 1,
         name_first: "test",
         name_middle: null,
         name_last: "user",
         email: "test@test.com",
       },
     ],
   }

以及关联的 mysql 日志条目:

Prepare   select * from `users` where CONCAT(name_first, " ", name_last) LIKE "%test%" and `users`.`deleted_at` is null
Execute   select * from `users` where CONCAT(name_first, " ", name_last) LIKE "%test%" and `users`.`deleted_at` is null
Close stmt

如果能提供任何关于为什么会发生这种情况的信息或建议,我们将不胜感激。

实际上那里有一个小问题(这是我对您 的解决方案)。当你使用这个:

User::whereRaw('CONCAT(name_first, " ", name_last) LIKE "%?%"', ['test']);

生成的 SQL 查询字符串将是这样的(在应用绑定之后):

select * from `users` where CONCAT(name_first, " ", name_last) LIKE "%'test'%" and `users`.`deleted_at` is null

由于引用的值是 test,因此您最终会得到 "%'test'%",这将不匹配任何内容。要解决这个问题,您应该将通配符移动到绑定数组中,如下所示:

 User::whereRaw('CONCAT(name_first, " ", name_last) LIKE ?', ['%' . $value . '%']);

现在该值将被正确引用:

select * from `users` where CONCAT(name_first, " ", name_last) LIKE '%test%' and `users`.`deleted_at` is null

对于您特别希望传递给查询生成器的参数不被转义的地方,也可以使用 DB::raw 的替代方法。所以在这种情况下,您可以像这样使用常规 where

User::where(DB::raw("CONCAT(name, ' ', email)"), 'LIKE', '%' . $value . '%');

这将确保连接部分不会被转义。