如何查看查询中的参数?

时间:2012-06-27 12:22:57

标签: mysql symfony doctrine-orm doctrine-query

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

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

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

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

想法?谢谢!

5 个答案:

答案 0 :(得分:27)

您可以使用$query->getParameters()访问占位符使用的参数,以便您可以使用以下命令调试查询:

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

答案 1 :(得分: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 (:?)中的参数通常是嵌套数组。

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

谢谢!

答案 2 :(得分: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一起使用,将参数替换为其值。

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

答案 3 :(得分:0)

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

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

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

$getSqlWithParams()->call($query)

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

答案 4 :(得分:0)

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