给定以下代码:
DB::table('users')->get();
我想得到上面的数据库查询生成器将生成的原始SQL查询字符串。在本例中,它将是SELECT*FROM用户。
我该怎么做?
给定以下代码:
DB::table('users')->get();
我想得到上面的数据库查询生成器将生成的原始SQL查询字符串。在本例中,它将是SELECT*FROM用户。
我该怎么做?
当前回答
虽然我很喜欢这个框架,但我讨厌它像垃圾一样运行。
DB::enableQueryLog()完全无用。DB::听同样没用。当我说$query->count()时,它显示了部分查询,但如果我执行$query->get(),它就没有什么好说的了。
唯一一个似乎能持续工作的解决方案是,故意在ORM参数中添加一些语法或其他错误,例如不存在的列/表名,在调试模式下在命令行上运行代码,最后将通过完整的“frickin”查询吐出SQL错误。否则,如果从web服务器运行,则希望错误出现在日志文件中。
其他回答
如果你使用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;
}
作为输入参数,可以使用以下任一项
照明\数据库\口才\生成器照亮\数据库\口才\关系\ HasMany照明\数据库\查询\生成器
最简单的方法是故意犯错误。例如,我想查看以下关系的完整SQL查询:
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_at','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
我只是想创建一个找不到的列,这里我选择了created_at,并通过添加尾随s将其更改为created_ats:
public function jobs()
{
return $this->belongsToMany(Job::class, 'eqtype_jobs')
->withPivot(['created_ats','updated_at','id'])
->orderBy('pivot_created_at','desc');
}
因此,调试器将返回以下错误:
(4/4)ErrorException SQLSTATE[42S22]:未找到列:1054未知“字段列表”中的列“eqtype_jobs.created_ats”(SQL:selectjobs.*,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.id上加入eqtype_jobs.job_id,其中eqtype_jobs.set_id=56在desc limit 20时按pivot_created排序偏移量0)(视图:/home/ssad/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
现在,只需从created_at中删除多余的s,并在任何SQL编辑器(如phpMyAdmin SQL编辑器)中测试该SQL!
###通知:该溶液已经用Laravel 5.4进行了测试。
$data = User::toSql();
echo $data; //this will retrun select * from users. //here User is model
我的方法是基于日志视图,只需修改app/Providers/AppServiceProvider.php文件:
将此代码添加到app/Provider/AppServiceProvider.php中
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
DB::listen(function ($query) {
$querySql = str_replace(['?'], ['\'%s\''], $query->sql);
$queryRawSql = vsprintf($querySql, $query->bindings);
Log::debug('[SQL EXEC]', [
"raw sql" => $queryRawSql,
"time" => $query->time,
]
);
});
}
我的sql句柄代码:
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, username '))
->where('uid', '>=', 10)
->limit(100)
->groupBy('username')
->get()
;
dd($users);
参见日志存储/logs/laravel-2019-10-27.log:
[2019-10-27 17:39:17] local.DEBUG: [SQL EXEC] {"raw sql":"select count(*) as user_count, username from `users` where `uid` >= '10' group by `username` limit 100","time":304.21}
我通过监听查询日志并附加到日志数组来实现:
//create query
$query=DB::table(...)...->where(...)...->orderBy(...)...
$log=[];//array of log lines
...
//invoked on query execution if query log is enabled
DB::listen(function ($query)use(&$log){
$log[]=$query;//enqueue query data to logs
});
//enable query log
DB::enableQueryLog();
$res=$query->get();//execute