为了调试我的代码,我想查看执行的显式 sql 查询。
我使用创建查询createQueryBuilder
,我实现的最明确的事情是使用原始查询:
$qb->getQuery()->getSQL();
问题是我看到的是持有者(?
)而不是参数。我在网上找到了一些解决方案,但它们适用于 1.3 和 1.4,不适用于 Symfony-2。
想法?谢谢!
为了调试我的代码,我想查看执行的显式 sql 查询。
我使用创建查询createQueryBuilder
,我实现的最明确的事情是使用原始查询:
$qb->getQuery()->getSQL();
问题是我看到的是持有者(?
)而不是参数。我在网上找到了一些解决方案,但它们适用于 1.3 和 1.4,不适用于 Symfony-2。
想法?谢谢!
您可以使用 访问占位符使用的参数$query->getParameters()
,因此您可以使用以下方法调试查询:
$query = $qb->getQuery();
print_r(array(
'sql' => $query->getSQL(),
'parameters' => $query->getParameters(),
));
您可以使用以下方法轻松访问 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
and $col_names
,您可以获取通过 sql 和相应列名的参数值。
注意:如果$param
返回一个数组,则需要重新迭代,因为里面的参数IN (:?)
通常是嵌套数组。
同时,如果您发现了另一种方法,请与我们分享 :)
谢谢!
我还一直在寻找一种从 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 一起使用以将参数替换为其值。
这当然是对核心代码的破解,由于我不熟悉为公共项目做出贡献,如果有人想尝试将其包含在其中,请随意复制它。
我必须建立一个 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 语句。瞧!
我会在 SQL Server 中使用 Profiler 来获取发送到数据库的内容。显然,mySQL 也有一些类似的工具。是否有与 MySql 等效的 Profiler?