我正在尝试调试我在测试套件中进行的一些SQL查询.使用以下调试代码:
\Log::debug(User::first()->jobs()->toSql());
Run Code Online (Sandbox Code Playgroud)
打印出来的SQL是:
`select * from `jobs` where `jobs`.`deleted_at` is null and `jobs`.`managed_by_id` = ? and `jobs`.`managed_by_id` is not null`
Run Code Online (Sandbox Code Playgroud)
在那里做那个问号是什么?我已经测试了查询,它按预期工作.是因为我正在选择第一个()用户发生这种情况吗?
Wad*_*der 16
Laravel使用Prepared Statements.它们是一种编写SQL语句而不直接将变量删除到SQL字符串中的方法.在?你看到的是稍后将取代和自动PDO消毒的信息占位符或绑定.有关预准备语句的更多信息,请参阅PHP文档http://php.net/manual/en/pdo.prepared-statements.php
要查看将替换为查询字符串的数据,您可以getBindings()在查询上调用该函数,如下所示.
$query = User::first()->jobs();
dd($query->toSql(), $query->getBindings());
Run Code Online (Sandbox Code Playgroud)
绑定数组的替换顺序?与SQL语句中出现的顺序相同.
只是重申@giovannipds 很好的答案...我正在这样做:
vsprintf(str_replace(['?'], ['\'%s\''], $query->toSql()), $query->getBindings())
Run Code Online (Sandbox Code Playgroud)
除了@wader的答案外,还有一种“宏”的方式来获取带有绑定的原始SQL查询。
在方法中添加以下宏功能。AppServiceProvider boot()
\Illuminate\Database\Query\Builder::macro('toRawSql', function(){
return array_reduce($this->getBindings(), function($sql, $binding){
return preg_replace('/\?/', is_numeric($binding) ? $binding : "'".$binding."'" , $sql, 1);
}, $this->toSql());
});
Run Code Online (Sandbox Code Playgroud)将别名添加到Eloquent Builder。
\Illuminate\Database\Eloquent\Builder::macro('toRawSql', function(){
return ($this->getQuery()->toRawSql());
});
Run Code Online (Sandbox Code Playgroud)然后照常调试。
\Log::debug(User::first()->jobs()->toRawSql());
Run Code Online (Sandbox Code Playgroud)注意:从Laravel 5.1到5.3,由于Eloquent Builder不使用
Macroable特征,因此无法动态toRawSql地向Eloquent Builder 添加别名。请按照下面的示例来实现相同的目的。
例如Eloquent Builder(Laravel 5.1-5.3)
\Log::debug(User::first()->jobs()->getQuery()->toRawSql());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30708 次 |
| 最近记录: |