symfony 如何查看查询中的参数?

uwopmtnx  于 12个月前  发布在  其他
关注(0)|答案(6)|浏览(125)

为了调试我的代码,我想看到显式的SQL查询执行。
我使用createQueryBuilder创建查询,我实现的最显式的事情是使用以下命令创建原始查询:

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

问题是,而不是参数,我看到的持有人(?)。我发现了一些解决方案,在网上,但他们是为1.3和1.4,没有为Symfony-2。
有主意吗?谢谢!

i34xakig

i34xakig1#

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

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

nfeuvbwi2#

您可以使用以下方法轻松访问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 (:?)内部的参数通常是嵌套的数组。
如果你发现了其他方法,请与我们分享:)
谢谢你,谢谢!

lyfkaqu1

lyfkaqu13#

我不得不建立一个互惠联盟(不可能与DQL或QueryBuilder)与5查询已经建立了与QueryBuilder.所以我重用这些查询,但我有一个问题,使用getParameters()函数,因为它给予相同的顺序,你已经给它的参数.当你使用查询生成器的优点之一是,你可以创建一个查询,按照你想要的顺序,但当你检索参数,你可能会在混乱中检索它。为了避免这种情况,我构建了以下函数:

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

现在,当你想检索SQL和排序参数时,你会这样做:

$getSqlWithParams()->call($query)

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

b5buobof

b5buobof4#

我也一直在寻找一种方法来从DQL查询中获得参数注入的SQL,以帮助调试,例如,允许我输出一个SQL字符串,我可以直接粘贴到phpmyadmin中,并向其添加解释等。
无论如何,我的答案基于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);
}

顾名思义,它执行查询以从解析器结果中获取参数Map,然后使用该Map和vsprintf沿着将参数替换为参数值。
当然,这是对核心代码的一种破解,由于我不熟悉为公共项目做贡献,如果有人想尝试将其包含在其中,请随意复制。

wi3ka0sx

wi3ka0sx5#

我会使用SQL Server中的Profiler来获取发送到数据库的内容。

vxf3dgd4

vxf3dgd46#

我的答案基于Néo对symfony 5.4的回答。

$getSqlParams = \Closure::bind(function(){
        $this->getSql();
        return $this->processParameterMappings($this->parserResult->getParameterMappings());
    }, $qb->getQuery(), Query::class);

    [$paramValueList, $paramTypeList] = $getSqlParams();

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

    $em->getConnection()->executeStatement($sql, $paramValueList, $paramTypeList);

相关问题