mei*_*ryo 470 php sql laravel laravel-4 laravel-query-builder
给出以下代码:
DB::table('users')->get();
Run Code Online (Sandbox Code Playgroud)
我想获取上面的数据库查询生成器将生成的原始SQL查询字符串.在这个例子中,它将是SELECT * FROM users.
我该怎么做呢?
Ste*_*nte 672
toSql()在QueryBuilder实例上使用该方法.
DB::table('users')->toSql() 会回来:
从`users`中选择*
这比连接事件监听器更容易,并且还允许您在构建时随时检查查询的实际外观.
jfo*_*ato 551
要输出到最后一次运行的查询,您可以使用它
DB::enableQueryLog(); // Enable query log
// Your Eloquent query
dd(DB::getQueryLog()); // Show results of log
Run Code Online (Sandbox Code Playgroud)
我相信最新的查询将位于数组的底部.
你会有类似的东西:
array(1) {
[0]=>
array(3) {
["query"]=>
string(21) "select * from "users""
["bindings"]=>
array(0) {
}
["time"]=>
string(4) "0.92"
}
}
Run Code Online (Sandbox Code Playgroud)
根据Joshua在下面的评论,现在默认关闭.要使用,您需要手动启用它:
DB::enableQueryLog(); // Enable query log
// Your Eloquent query
dd(DB::getQueryLog()); // Show results of log
Run Code Online (Sandbox Code Playgroud)
Kak*_*shi 61
DB::QueryLog()只有在执行查询后才能工作$builder->get().如果要在执行查询之前获取查询,可以使用$builder->toSql()方法.这是如何获取sql并绑定它的示例:
$query = str_replace(array('?'), array('\'%s\''), $builder->toSql());
$query = vsprintf($query, $builder->getBindings());
dump($query);
$result = $builder->get();
Run Code Online (Sandbox Code Playgroud)
Rub*_*zzo 55
您可以收听'illuminate.query'事件.在查询之前添加以下事件侦听器:
Event::listen('illuminate.query', function($query, $params, $time, $conn)
{
dd(array($query, $params, $time, $conn));
});
DB::table('users')->get();
Run Code Online (Sandbox Code Playgroud)
这将打印出如下内容:
array(4) {
[0]=>
string(21) "select * from "users""
[1]=>
array(0) {
}
[2]=>
string(4) "0.94"
[3]=>
string(6) "sqlite"
}
Run Code Online (Sandbox Code Playgroud)
Luk*_*den 48
如果您尝试使用Illuminate而不使用Laravel来使用Log:
\Illuminate\Database\Capsule\Manager::getQueryLog();
Run Code Online (Sandbox Code Playgroud)
你也可以像这样快速启动一个函数:
function logger() {
$queries = \Illuminate\Database\Capsule\Manager::getQueryLog();
$formattedQueries = [];
foreach( $queries as $query ) :
$prep = $query['query'];
foreach( $query['bindings'] as $binding ) :
$prep = preg_replace("#\?#", is_numeric($binding) ? $binding : "'" . $binding . "'", $prep, 1);
endforeach;
$formattedQueries[] = $prep;
endforeach;
return $formattedQueries;
}
Run Code Online (Sandbox Code Playgroud)
编辑
更新版本似乎默认禁用查询日志记录(上面返回一个空数组).要重新启动,在初始化Capsule Manager时,请获取连接实例并调用该enableQueryLog方法
$capsule::connection()->enableQueryLog();
Run Code Online (Sandbox Code Playgroud)
再次编辑
考虑到实际问题,您实际上可以执行以下操作来转换当前单个查询而不是所有先前的查询:
$sql = $query->toSql();
$bindings = $query->getBindings();
Run Code Online (Sandbox Code Playgroud)
Cel*_*cca 36
在eloquent中有一种获取查询字符串的方法.
toSql()
在我们的例子中,
DB::table('users')->toSql();
Run Code Online (Sandbox Code Playgroud)
返回
select * from users
Run Code Online (Sandbox Code Playgroud)
是返回SQL查询字符串的确切解决方案.希望这有用...
Kul*_*hra 27
$data = User::toSql();
echo $data; //this will retrun select * from users. //here User is model
Run Code Online (Sandbox Code Playgroud)
Yev*_*yev 24
如果你使用laravel 5.1和MySQL,你可以使用我的这个功能:
/*
* returns SQL with values in it
*/
function getSql($model)
{
$replace = function ($sql, $bindings)
{
$needle = '?';
foreach ($bindings as $replace){
$pos = strpos($sql, $needle);
if ($pos !== false) {
if (gettype($replace) === "string") {
$replace = ' "'.addslashes($replace).'" ';
}
$sql = substr_replace($sql, $replace, $pos, strlen($needle));
}
}
return $sql;
};
$sql = $replace($model->toSql(), $model->getBindings());
return $sql;
}
Run Code Online (Sandbox Code Playgroud)
作为输入参数,您可以使用其中任何一个
照亮\数据库\雄辩\生成器
照亮\数据库\雄辩\关系\的hasMany
照亮\数据库\查询\生成器
Gre*_*reg 13
从 Laravel 5.8.15 开始,查询构建器现在拥有 dd和dump方法,因此您可以执行
DB::table('data')->where('a', 1)->dump();
Run Code Online (Sandbox Code Playgroud)
Rav*_*ane 11
首先您需要通过调用以下命令启用查询日志:
DB::enableQueryLog();
Run Code Online (Sandbox Code Playgroud)
在使用数据库外观查询后,您可以编写:
dd(DB::getQueryLog());
Run Code Online (Sandbox Code Playgroud)
输出如下:
array:1 [?
0 => array:3 [?
"query" => "select * from `users` left join `website_user` on `users`.`id` = `website_user`.`user_id` left join `region_user` on `users`.`id` = `region_user`.`user_id` left ?"
"bindings" => array:5 [?]
"time" => 3.79
]
]
Run Code Online (Sandbox Code Playgroud)
rah*_*ori 11
在我看来,这将是初学者的最佳方法:
echo "<pre>";
print_r($query->toSql());
print_r($query->getBindings());
Run Code Online (Sandbox Code Playgroud)
这也被描绘在这里。 /sf/answers/4144529021/
Sag*_*ara 10
你可以使用toSql()方法做以下事情,
$query = DB::table('users')->get();
echo $query->toSql();
Run Code Online (Sandbox Code Playgroud)
如果它不起作用,您可以从laravel文档中设置该东西.
另一种方法是
DB::getQueryLog()
但如果它返回一个空数组,那么默认情况下它被禁用访问这个,
只需启用,DB::enableQueryLog()它将工作:)
欲了解更多信息,请访问Github Issue以了解更多相关信息.
希望能帮助到你 :)
Ija*_*een 10
一个“macroable”更换,以获得与绑定的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)为雄辩的生成器添加别名。(Laravel 5.4+)
\Illuminate\Database\Eloquent\Builder::macro('toRawSql', function(){
return ($this->getQuery()->toRawSql());
});
Run Code Online (Sandbox Code Playgroud)然后照常调试。(Laravel 5.4+)
例如查询生成器
\Log::debug(\DB::table('users')->limit(1)->toRawSql())
Run Code Online (Sandbox Code Playgroud)
例如雄辩的建造者
\Log::debug(\App\User::limit(1)->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(\App\User::limit(1)->getQuery()->toRawSql());
Run Code Online (Sandbox Code Playgroud)
jus*_*ajm 10
这是我可以建议的任何一种最佳解决方案,用于调试有说服力的最后查询或最终查询,尽管对此也进行了讨论:
// query builder
$query = DB::table('table_name')->where('id', 1);
// binding replaced
$sql = str_replace_array('?', $query->getBindings(), $query->toSql());
// for laravel 5.8^
$sql = Str::replaceArray('?', $query->getBindings(), $query->toSql());
// print
dd($sql);
Run Code Online (Sandbox Code Playgroud)
Dha*_*mik 10
将此函数添加到您的应用程序中,只需调用即可。
function getQuery($sql){
$query = str_replace(array('?'), array('\'%s\''), $sql->toSql());
$query = vsprintf($query, $sql->getBindings());
return $query;
}
Run Code Online (Sandbox Code Playgroud)
输出:“select * from userwhere lang= 'en' and status= '1' order by updated_atdesc limit 25 offset 0”
toRawSQL()使用最新版本的 Laravel 10,您现在可以通过在 QueryBuilder 上使用来输出包括绑定的 SQL 查询:
User::where('email', 'foo@example.com')->toRawSql();
// "SELECT * FROM users WHERE email = 'foo@example.com'"
Run Code Online (Sandbox Code Playgroud)
新的dd()输出也可能很方便:
User::where('email', 'foo@example.com')->dd();
// "SELECT * FROM users WHERE email = ?"
// [
// 0 => "foo@example.com"
// ]
Run Code Online (Sandbox Code Playgroud)
请参阅Laravel 新闻公告以获取更多信息
小智 8
使用debugbar包
composer require "barryvdh/laravel-debugbar": "2.3.*"
Run Code Online (Sandbox Code Playgroud)
从laravel 5.2和向前.您可以使用它DB::listen来获取执行的查询.
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
Run Code Online (Sandbox Code Playgroud)
或者,如果要调试单个Builder实例,则可以使用toSql方法.
DB::table('posts')->toSql();
Run Code Online (Sandbox Code Playgroud)
最简单的方法是故意犯错误。例如,我想查看以下关系的完整SQL查询:
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_at','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
Run Code Online (Sandbox Code Playgroud)
我只是要创建一个找不到的列,在这里我选择了created_at,然后created_ats通过添加尾随s将其更改为:
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_ats','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
Run Code Online (Sandbox Code Playgroud)
因此,调试器将返回以下错误:
(4/4)ErrorException SQLSTATE [42S22]:柱未找到:在'字段列表' 1054未知列'eqtype_jobs.created_ats'(SQL:选择
jobs*,。eqtype_jobs。set_id如pivot_set_id,eqtype_jobs。job_id如pivot_job_id,eqtype_jobs。created_ats如pivot_created_ats,eqtype_jobs。updated_at如pivot_updated_at,eqtype_jobs。id如pivot_id从jobs内连接eqtype_jobs上jobs。id=eqtype_jobs。job_id其中eqtype_jobs。set_id= 56为了通过pivot_created_at递减限20偏移0)(查看:/home/said/www/factory/resources/views/set/show.blade.php)
上面的错误消息返回带有错误的完整SQL查询
SQL: select jobs.*, eqtype_jobs.set_id as pivot_set_id, eqtype_jobs.job_id as pivot_job_id, eqtype_jobs.created_ats as pivot_created_ats, eqtype_jobs.updated_at as pivot_updated_at, eqtype_jobs.id as pivot_id from jobs inner join eqtype_jobs on jobs.id = eqtype_jobs.job_id where eqtype_jobs.set_id = 56 order by pivot_created_at desc limit 20 offset 0
Run Code Online (Sandbox Code Playgroud)
现在,只需s从created_at中删除多余的内容,然后在任何SQL编辑器(例如phpMyAdmin SQL编辑器)中测试此SQL!
注意:
该解决方案已通过Laravel 5.4进行了测试。
小智 7
您可以使用 toSql 方法 - 最简单的方法
DB::table('users')->toSql();
Run Code Online (Sandbox Code Playgroud)
另外,如果您的查询中有绑定并且想要查看带有绑定的查询。你不能使用这样的东西:
$query = DB::table('table')->whereIn('some_field', [1,2,30]);
$sql_with_bindings = str_replace_array('?', $query->getBindings(), $query->toSql());
dd($sql_with_bindings);
Run Code Online (Sandbox Code Playgroud)
小智 7
为了记录所有执行的查询,您可以使用DB::enableQueryLog() icw DB::getQueryLog()。输出具有以下结构。
[
[
"query" => "select * from "users" where name = ?"
"bindings" => ["John Doe"]
"time" => 0.34
],
...
]
Run Code Online (Sandbox Code Playgroud)
此外,我在这里组合了一些答案,以获得使用编译的绑定解析 sql 的完美函数。见下文。我什至创建了一个实现此功能的自定义构建器类,以便执行 User::where('name','John Doe')->parse(); 等操作。
function parse_sql(string $sql, array $bindings) : string
{
$compiled_bindings = array_map('compile_binding', $bindings);
return preg_replace_array("/\?/", $compiled_bindings, $sql);
}
function compile_binding($binding)
{
$grammar = new MySqlGrammar;
if (is_bool($binding))
{
return (int)$binding; //This line depends on the database implementation
}
if(is_string($binding))
{
return "'$binding'";
}
if ($binding instanceof DateTimeInterface)
{
return $binding->format($grammar->getDateFormat());
}
return $binding;
}
Run Code Online (Sandbox Code Playgroud)
DB::enableQueryLog();
$queries = DB::getQueryLog();
Run Code Online (Sandbox Code Playgroud)
这是函数,我放在我的基础模型类中.只需将查询构建器对象传递给它,就会返回SQL字符串.
function getSQL($builder) {
$sql = $builder->toSql();
foreach ( $builder->getBindings() as $binding ) {
$value = is_numeric($binding) ? $binding : "'".$binding."'";
$sql = preg_replace('/\?/', $value, $sql, 1);
}
return $sql;
}
Run Code Online (Sandbox Code Playgroud)
尝试这个:
$results = DB::table('users')->toSql();
dd($results);
Run Code Online (Sandbox Code Playgroud)
注意:get() 已替换为 toSql() 以显示原始 SQL 查询。
已经回答了很多信息,只要我需要在执行之前输出 sql 查询,我就会发布我自己的发现。
考虑以下示例:
$user = DB::table('user')->where('id',1);
echo $user->toSql();
Run Code Online (Sandbox Code Playgroud)
echo $user->toSql() = 这只会输出原始查询,但不会显示传递的参数。
要使用传递的参数输出查询,我们可以像这样使用 laravel getBindings()和 helper str_replace_array:
$queryWithParam = str_replace_array('?',$user->getBindings(),$user->toSql());
echo $queryWithParam;
Run Code Online (Sandbox Code Playgroud)
希望这也有帮助。
| 归档时间: |
|
| 查看次数: |
523726 次 |
| 最近记录: |