如何获取查询构建器以使用内联参数输出其原始SQL查询

时间:2018-10-04 13:48:51

标签: php sql laravel

给出以下代码:

TEdit *e = dynamic_cast<TEdit *>(MyObject);
if (e != NULL)
    e->Text = "Hello, world!";
  1. 我得到了原始SQL查询字符串,但它使用了参数。

    DB::table('users')->where( 'gender' , '=', 'male', true)->toSql();
    

    我可以以某种方式内联参数吗?

  2. 我可以对构建器说不使用反引号吗?现在我使用select * from `users` where `gender`=? 表达式,但是我不想使用它。

5 个答案:

答案 0 :(得分:1)

您正在寻找getBindings()方法来获取实际参数。所以这样的事情应该起作用:

$completeSql = str_replace_array('?', $query->getBindings(), $query->toSql());

https://laravel.com/docs/5.7/helpers#method-str-replace-array,获取有关str_replace_array()帮助器的信息,该帮助器在此处效果很好。

我认为DB :: raw()是避免反引号而不扩展内容的方法。

反引号添加到MySqlGrammar wrapValue()方法中。您可以扩展该类,然后覆盖您不喜欢的部分。然后您应该可以使用

DB::connection()->setSchemaGrammar(new YourExtendedMySqlGrammar());

https://laravel.com/docs/5.7/queries#raw-expressions中有关原始表达式的信息也可能有用。

答案 1 :(得分:0)

echo sprintf(str_replace('?', '%s',DB::table('users')->where( 'gender' , '=', 'male', true)->toSql()), 'male');

或者,您可以在数据库中打开查询记录,然后在其中查看它们

答案 2 :(得分:0)

Laravel Debugbar为您开箱即用,几乎不需要代码。所有查询及其参数都显示在查询选项卡中,并且可以复制/粘贴到您选择的任何SQL客户端中。

https://github.com/barryvdh/laravel-debugbar

答案 3 :(得分:0)

如果这不是用于调试,则可以使用api/facebookuser

getBindings()

很明显,这仅适用于单值类型,例如int,日期,字符串等。如果有数组,则需要转换$q = \DB::table('contact')->where('created_at', '2018-01-01'); $sql = $q->toSql(); $bind = $q->getBindings(); $inline = vsprintf(str_replace("?", "'%s'", $sql), $bind); echo $inline; ,因此其值仅是字符串。

答案 4 :(得分:0)

前一段时间,我想要一个调试工具,该工具可以显示完整,易于阅读,复制/可粘贴的SQL。当时,我正使用它来暴露影响性能的N + 1个惰性负载。因此,我实际上剖析了DebugBar来弄清楚他们是如何管理它的,并提出了听起来也很适合您的目的的东西。

这基本上只是重新格式化Laravel在查询日志中捕获的内容。 (当然,它们实际上必须完成执行才能在此处可见。)只需确保,如果您使用的是任何raw方法,则将字段名称封装在反引号中,否则大写看起来会有点僵硬的。

DB::enableQueryLog();
DB::flushQueryLog();

//Execute whatever code results in SQL queries

$queries = DB::getQueryLog();
DB::disableQueryLog();
DB::flushQueryLog();

$dbName = null;
$compiled = [];
foreach ($queries as $query) {
    if (DB::getDatabaseName() != $useDb) {
        $dbName = DB::getDatabaseName();
        $compiled[] = "USE `$dbName`;";
    }

    $sql = $query['query'];
    $values = $query['bindings'];

    $enclosures = [
        'back_tick' => '`',
        'apostrophe' => "'"
    ];

    $matches = [];
    foreach ($enclosures as $name => $enclosure) {
        $matches[$name] = [];
        preg_match_all("/$enclosure.*?$enclosure/", $sql, $matches[$name]);
        $matches[$name] = array_last($matches[$name]);
        $sql = preg_replace("/$enclosure.*?$enclosure/", "$enclosure?$enclosure", $sql);
    }

    $sql = strtoupper($sql);

    foreach ($enclosures as $name => $enclosure) {
        $sql = str_replace_array("$enclosure?$enclosure", $matches[$name], $sql);
    }

    $values = array_map(function ($value) {
        if (!is_numeric($value) && !is_null($value)) {
            $value = DB::connection()->getPdo()->quote($value);
        }
        return $value;
    }, $values);

    $sql = str_replace_array('?', $values, $sql);
    $sql = rtrim($sql, ';').';';

    $compiled[] = $sql;
}

顺便说一句,DB::getQueryLog()还包括运行查询所花费的时间,这对于诊断性能问题更加有用。请记住,连接时间是一个因素。在本地托管要迁移到数据库中的应用程序所需的时间要比实际项目实际需要的时间长。