如何查看查询中的参数?

Posted

技术标签:

【中文标题】如何查看查询中的参数?【英文标题】:How do I view the parameters in a query? 【发布时间】:2012-06-28 21:05:33 【问题描述】:

为了调试我的代码,我想查看执行的显式 sql 查询。

我使用createQueryBuilder 创建查询,我实现的最明确的事情是使用原始查询:

$qb->getQuery()->getSQL();

问题是,我看到的不是参数,而是持有者 (?)。 我在网上找到了一些解决方案,但它们适用于 1.3 和 1.4,不适用于 Symfony-2。

想法?谢谢!

【问题讨论】:

其实你的问题是这个***.com/q/2095394/795876的重复。 Doctrine 正在使用准备好的语句,因此 php 端从来没有“真正的”SQL 查询,Doctrine 无法显示它。但是,您可以阅读此解决方案 ***.com/a/10577703/795876 以进行调试。 另外,学说 2 有 sqlLogger 类:doctrine-orm.readthedocs.org/en/2.0.x/reference/… fsehat - 看起来这个解决方案适用于 Symfony 1.4,我在整个项目中既找不到 getSqlQuery 函数也找不到 getFlattenedParams (这是我失踪了)。 manix - 你有更多关于如何在 Symfony 2.x 中使用记录器的参考资料吗?它看起来像一个很好的解决方案,但我没有找到任何好的文档。 谢谢你们! 【参考方案1】:

您可以使用$query->getParameters() 访问占位符使用的参数,因此您可以使用以下方法调试您的查询:

$query = $qb->getQuery();
print_r(array(
    'sql'        => $query->getSQL(),
    'parameters' => $query->getParameters(),
));

【讨论】:

基本上这是个好主意。问题是参数包可能包含对象,然后尝试打印它会给出巨大的字符串。我想做的是将$query->getParameters()返回的参数包转换为可以替换占位符?的字符串数组。 我认为这个数组已经是一个标量值数组,如果你看一下 setParameter 方法 github.com/doctrine/doctrine2/blob/2.2/lib/Doctrine/ORM/… ,它会调用将数组和对象转换为标量值的 processParameterValue github.com/doctrine/doctrine2/blob/2.2/lib/Doctrine/ORM/… 有趣的是,我得到了(据我所知......)所有供应商的最后一个版本,而我的 AbstractQuery.phpQuery.php 有点不同。可能我拥有的是 Doctrine 2.1,而这段代码是 2.2。无论如何,我在Query.php 文件中添加了一个方法,该方法根据您的回答返回原始 sql + 参数。谢谢! 据我所知,您可以取回的数据远不如您输入的有用。getSQL() 显示? 占位符,即使您使用了:namedPlaceholdersgetParamaters() 没有说明它与这些占位符的关系。使用 3 个占位符和两个键/对(在语句中重用一个参数)的语句,你怎么知道要在哪里插入什么值?【参考方案2】:

您可以使用以下方法轻松访问 SQL 参数。

   $result = $qb->getQuery()->getSQL();

   $param_values = '';  
   $col_names = '';   

   foreach ($result->getParameters() as $index => $param)              
            $param_values .= $param->getValue().',';
            $col_names .= $param->getName().',';
    

   //echo rtrim($param_values,',');
   //echo rtrim($col_names,',');    

所以如果你把$param_values$col_names打印出来,就可以得到通过sql传递的参数值和各自的列名。

注意:如果$param返回一个数组,则需要重新迭代,因为IN (:?)里面的参数通常是嵌套数组。

同时,如果您发现了另一种方法,请与我们分享 :)

谢谢!

【讨论】:

【参考方案3】:

我必须建立一个 requete union(使用 DQL 或 QueryBuilder 不可能),其中已经使用 QueryBuilder 构建了 5 个查询。所以我重用了这些查询,但我在使用 getParameters() 函数时遇到了问题,因为它以与你给出的相同顺序给出参数。使用查询构建器的优点之一是您可以按您想要的顺序创建查询,但是当您检索参数时,您可能会在检索时混乱。 为避免这种情况,我构建了以下功能:

    $getSqlWithParams = \Closure::bind(function()
        return [$this->getSql(), $this->processParameterMappings($this->_parserResult->getParameterMappings())];
    , null, Query::class);

现在当你想要检索 sql 和你做的排序参数时:

$getSqlWithParams()->call($query)

不要忘记使用 \Doctrine\ORM\Query 语句。 瞧!

【讨论】:

【参考方案4】:

我还一直在寻找一种从 DQL 查询中获取参数注入 SQL 的方法,以帮助调试,例如,允许我输出一个可以直接粘贴到 phpmyadmin 中的 SQL 字符串,并为其添加说明等。

无论如何,我的答案基于 Néo 的答案,由于私有方法调用,我无法让它工作,我通过在 Doctrine\ORM\Query 中创建一个函数来进行调整,如下所示:

/**
 * Execute query and return the SQL with params injected.
 *
 * @return string
 * @throws QueryException
 */
public function executeAndGetSqlWithParams(): string

    // Execute the query to get the parser result.
    $this->execute();

    // Declare the SQL for use in the vsprintf function.
    $sql = str_replace('?', '%s', $this->getSQL());

    // Declare the SQL parameter mappings.
    $parameterMappings = $this->processParameterMappings($this->_parserResult->getParameterMappings());

    /**
     * TODO: Possibly replace each question mark by the correct vsprintf argument using $parameterMappings[1].
     *
     * Right now all parameters are treated as strings.
     */

    // Declare and define the SQL parameters.
    $sqlParameters = [];

    foreach ($parameterMappings[0] as $parameter)
    
        if (is_array($parameter))
        
            $sqlParameters[] = implode(',', $parameter);
        
        else
        
            $sqlParameters[] = $parameter;
        
    

    // Return the SQL with its parameters injected.
    return vsprintf($sql, $sqlParameters);

顾名思义,它执行查询以从解析器结果中获取参数映射,然后将其与 vsprintf 一起使用以将参数替换为其值。

这当然是对核心代码的破解,由于我不熟悉为公共项目做出贡献,如果有人想尝试将其包含在其中,请随意复制。

【讨论】:

【参考方案5】:

我会在 SQL Server 中使用 Profiler 来获取发送到数据库的内容。显然,mysql 也有一些类似的工具。 Is there a Profiler equivalent for MySql?

【讨论】:

以上是关于如何查看查询中的参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何查看oracle数据库配置参数?

如何查看电脑参数

mysql如何找出慢sql

Mysql中如何查看慢查询以及查看线程

如何查看DLL中的函数信息

如何查看mysql版本