给定以下代码:

DB::table('users')->get();

我想得到上面的数据库查询生成器将生成的原始SQL查询字符串。在本例中,它将是SELECT*FROM用户。

我该怎么做?


当前回答

如果您正在使用修补程序并希望记录形成的SQL查询,可以执行以下操作

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.5 — cli) by Justin Hileman
>>> DB::listen(function ($query) { dump($query->sql); dump($query->bindings); dump($query->time); });
=> null
>>> App\User::find(1)
"select * from `users` where `users`.`id` = ? limit 1"
array:1 [
  0 => 1
]
6.99
=> App\User {#3131
     id: 1,
     name: "admin",
     email: "admin@example.com",
     created_at: "2019-01-11 19:06:23",
     updated_at: "2019-01-11 19:06:23",
   }
>>>

其他回答

我创建了一些简单的函数来从一些查询中获取SQL和绑定。

/**
 * getSql
 *
 * Usage:
 * getSql( DB::table("users") )
 * 
 * Get the current SQL and bindings
 * 
 * @param  mixed  $query  Relation / Eloquent Builder / Query Builder
 * @return array          Array with sql and bindings or else false
 */
function getSql($query)
{
    if( $query instanceof Illuminate\Database\Eloquent\Relations\Relation )
    {
        $query = $query->getBaseQuery();
    }

    if( $query instanceof Illuminate\Database\Eloquent\Builder )
    {
        $query = $query->getQuery();
    }

    if( $query instanceof Illuminate\Database\Query\Builder )
    {
        return [ 'query' => $query->toSql(), 'bindings' => $query->getBindings() ];
    }

    return false;
}

/**
 * logQuery
 *
 * Get the SQL from a query in a closure
 *
 * Usage:
 * logQueries(function() {
 *     return User::first()->applications;
 * });
 * 
 * @param  closure $callback              function to call some queries in
 * @return Illuminate\Support\Collection  Collection of queries
 */
function logQueries(closure $callback) 
{
    // check if query logging is enabled
    $logging = DB::logging();

    // Get number of queries
    $numberOfQueries = count(DB::getQueryLog());

    // if logging not enabled, temporarily enable it
    if( !$logging ) DB::enableQueryLog();

    $query = $callback();

    $lastQuery = getSql($query);

    // Get querylog
    $queries = new Illuminate\Support\Collection( DB::getQueryLog() );

    // calculate the number of queries done in callback
    $queryCount = $queries->count() - $numberOfQueries;

    // Get last queries
    $lastQueries = $queries->take(-$queryCount);

    // disable query logging
    if( !$logging ) DB::disableQueryLog();

    // if callback returns a builder object, return the sql and bindings of it
    if( $lastQuery )
    {
        $lastQueries->push($lastQuery);
    }

    return $lastQueries;
}

用法:

getSql( DB::table('users') );
// returns 
// [
//     "sql" => "select * from `users`",
//     "bindings" => [],
// ]

getSql( $project->rooms() );
// returns
// [
//     "sql" => "select * from `rooms` where `rooms`.`project_id` = ? and `rooms`.`project_id` is not null",
//     "bindings" => [ 7 ],
// ]

第一种方式:

只需使用toSql()方法,

$query = DB::table('users')->get();

echo $query->toSql();

如果它不起作用,你可以从laravel文档中设置它。

第二种方式:

另一种方法是

数据库::getQueryLog()

但是如果它返回一个空数组,那么默认情况下它被禁用,

只需使用DB::enableQueryLog()启用即可:)

有关更多信息,请访问Github Issue了解更多信息。

希望有帮助:)

我的方法是基于日志视图,只需修改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} 

最简单的方法是故意犯错误。例如,我想查看以下关系的完整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进行了测试。

如果您正在使用修补程序并希望记录形成的SQL查询,可以执行以下操作

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.5 — cli) by Justin Hileman
>>> DB::listen(function ($query) { dump($query->sql); dump($query->bindings); dump($query->time); });
=> null
>>> App\User::find(1)
"select * from `users` where `users`.`id` = ? limit 1"
array:1 [
  0 => 1
]
6.99
=> App\User {#3131
     id: 1,
     name: "admin",
     email: "admin@example.com",
     created_at: "2019-01-11 19:06:23",
     updated_at: "2019-01-11 19:06:23",
   }
>>>