繁体   English   中英

从 Laravel 查询生成器生成原始 MySQL 查询

[英]Generate The Raw MySQL Query From Laravel Query Builder

我如何获得laravel查询的mysql查询

转变:

App\User::where('balance','>',0)->where(...)->get();

到:

SELECT * FROM users WHERE `balance`>0 and ...

使用toSql()方法来获取要执行的查询,如

App\User::where('balance','>',0)->where(...)->toSql();

但是 Laravel 不会在您的查询中显示参数,因为它们是在准备好查询之后绑定的。 要获取绑定参数,请使用此

$query=App\User::where('balance','>',0)->where(...);
print_r($query->getBindings() );

将查询日志启用为DB::enableQueryLog() ,然后将上次运行的查询输出到屏幕上,您可以使用它,

dd(DB::getQueryLog());

您可以将此功能添加到您的助手中

function getRealQuery($query, $dumpIt = false)
{
    $params = array_map(function ($item) {
        return "'{$item}'";
    }, $query->getBindings());
    $result = str_replace_array('\?', $params, $query->toSql());
    if ($dumpIt) {
        dd($result);
    }
    return $result;
}

并像这样使用:

getRealQuery(App\User::where('balance','>',0)->where(...),true)

这是一个辅助函数,它告诉您最后执行的 SQL。

use DB;
public static function getLastSQL()
{
    $queries = DB::getQueryLog();
    $last_query = end($queries);
          // last_query is the SQL with with data binding like 
          //   { 
          //       select ? from sometable where field = ? and field2 = ? ;
          //       param1,
          //       param2,
          //       param3,
          //   }
          //   which is hard to read.
    $last_query = bindDataToQuery($last_query);     
          // here, last_query is the last SQL you have executed as normal SQL
          //     select param1 from sometable where field=param2 and field2 = param3;
    return $last_query
}

这里是 bindDataToQuery 函数,谁填写了“?” 带有真实参数的空白。

protected static function bindDataToQuery($queryItem){
    $query = $queryItem['query'];
    $bindings = $queryItem['bindings'];
    $arr = explode('?',$query);
    $res = '';
    foreach($arr as $idx => $ele){
        if($idx < count($arr) - 1){
            $res = $res.$ele."'".$bindings[$idx]."'";
        }
    }
    $res = $res.$arr[count($arr) -1];
    return $res;
}

方法一

要打印单个查询,请使用 laravel 的 toSql() 方法来获取要执行的查询,例如

App\User::where('balance','>',0)->where(...)->toSql();

方法二

Laravel 可以选择将所有针对当前请求运行的查询记录到内存中。 但是在某些情况下,例如插入大量行时,这会导致应用程序使用过多的内存,因此应避免这种情况。

要启用日志,您可以使用enableQueryLog方法作为

DB::connection()->enableQueryLog();

要获取已执行查询的数组,您可以使用getQueryLog方法作为

$queries = DB::getQueryLog();

您可以在此处获得更多详细信息Laravel 启用查询日志

方法三

另一种显示 Laravel 中使用的所有查询而不启用查询日志的方法从这里Laravel Debug Bar安装LaravelDebugBar 它是一个包,可让您在开发过程中快速轻松地密切关注您的应用程序。

奇怪的是,laravel 还不支持任何方式轻松获取原始 sql,毕竟现在是 6 版......

这是我自己使用的一种解决方法,用于在不安装任何扩展的情况下快速获取带参数的原始 sql...

只是故意让你原来的sql出错

喜欢改变

DB::table('user')

DB::table('user1')

表“user1”根本不存在!

然后再次运行它。

当然,laravel 会报告一个异常。

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'user1' doesn't exist (SQL: ...)

现在你可以看到带有参数的原始 sql 就在字符串“(SQL:”

从错误的表名改回正确的表名,然后就可以了!

要打印原始 sql 查询,请尝试:

DB::enableQueryLog();
// Your query here
$queries = DB::getQueryLog();
print_r($queries);

参考

在 Laravel 5.4 中(我没有在其他版本中检查),将此功能添加到 "App"=>"Providers"=>"AppServiceProvider.php" 中。

public function boot()
{

    if (App::isLocal()) {

        DB::listen(
            function ($sql) {
                // $sql is an object with the properties:
                //  sql: The query
                //  bindings: the sql query variables
                //  time: The execution time for the query
                //  connectionName: The name of the connection

                // To save the executed queries to file:
                // Process the sql and the bindings:
                foreach ($sql->bindings as $i => $binding) {
                    if ($binding instanceof \DateTime) {
                        $sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
                    } else {
                        if (is_string($binding)) {
                            $sql->bindings[$i] = "'$binding'";
                        }
                    }
                }

                // Insert bindings into query
                $query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);

                $query = vsprintf($query, $sql->bindings);

                // Save the query to file
                /*$logFile = fopen(
                    storage_path('logs' . DIRECTORY_SEPARATOR . date('Y-m-d') . '_query.log'),
                    'a+'
                );*/
                Log::notice("[USER] $query");
            }
        );
    }
}

安装后, https://github.com/ARCANEDEV/LogViewer ,然后您无需编辑代码即可查看每个已执行的 SQL 查询。

要在 Laravel 中获取 mysql 查询,您需要将查询记录为

DB::enableQueryLog();
App\User::where('balance','>',0)->where(...)->get();
print_r(DB::getQueryLog());

检查参考: https : //laravel.com/docs/5.0/database#query-logging

当我想查看生成的 SQL 时,我没有用打印语句或“ dd s”干扰应用程序,而是执行以下操作:

DB::listen(function ($query) { 
    Log::info($query->sql, $query->bindings);
});

// (DB and Log are the facades in Illuminate\Support\Facades namespace)

这会将 sql 输出到 Laravel 日志(位于storage/logs/laravel.log )。 跟踪写入此文件的有用命令是

tail -n0 -f storage/logs/laravel.log

无需任何代码更改即可显示 Laravel 中使用的所有查询的一种简单方法是安装 LaravelDebugBar ( https://laravel-news.com/laravel-debugbar )。

作为功​​能的一部分,您将获得一个选项卡,该选项卡将显示页面已使用的所有查询。

尝试这个:

$results = App\User::where('balance','>',0)->where(...)->toSql();
dd($results);

注意:get() 已替换为 toSql() 以显示原始 SQL 查询。

一个非常简单快捷的方法是在下面写出错误的列名称,例如写 'balancedd' 尽管有 'balance',并且当您执行带有所有参数和未找到该列的错误的代码时,查询将显示在错误屏幕上。

DB::enableQueryLog(); (Query) $d= DB::getQueryLog(); print"<pre>"; print_r ($d); print"</pre>";

您将获得刚刚运行的 mysql 查询。

在 Laravel 甚至 PHP 中实际上没有这样的事情,因为 PHP 在内部将带有查询字符串的参数发送到数据库,在那里它(可能)被解析为原始查询字符串。

接受的答案实际上是乐观的解决方案,有点“可选工作”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM