为了调试我的代码,我希望看到执行的显式sql查询。
我使用createQueryBuilder
创建查询,我实现的最明确的事情是使用原始查询:
$qb->getQuery()->getSQL();
问题在于,我看到持有者(?
)而不是参数。
我在网上找到了一些解决方案,但它们分别用于1.3和1.4,而没有用于Symfony-2。
想法?谢谢!
答案 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?