11

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

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

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

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

想法?谢谢!

4

5 回答 5

28

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

$query = $qb->getQuery();
print_r(array(
    'sql'        => $query->getSQL(),
    'parameters' => $query->getParameters(),
));
于 2012-07-07T23:43:34.917 回答
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_valuesand $col_names,您可以获取通过 sql 和相应列名的参数值。

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

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

谢谢!

于 2015-02-03T08:35:44.543 回答
1

我还一直在寻找一种从 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 一起使用以将参数替换为其值。

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

于 2018-04-06T18:39:09.137 回答
1

我必须建立一个 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 语句。瞧!

于 2017-03-27T18:45:59.460 回答
0

我会在 SQL Server 中使用 Profiler 来获取发送到数据库的内容。显然,mySQL 也有一些类似的工具。是否有与 MySql 等效的 Profiler?

于 2018-04-06T18:44:09.710 回答