コードをデバッグするために、実行される明示的な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
_と_$col_names
_を出力すると、SQLとそれぞれの列名を通過するパラメーター値を取得できます。
注:_$param
_が配列を返す場合、IN (:?)
内のパラメーターは通常ネストされた配列であるため、繰り返す必要があります。
その間、別のアプローチを見つけた場合は、私たちと共有するのに十分親切にしてください:)
ありがとうございました!
また、DQLクエリからパラメータが挿入されたSQLを取得して、たとえばphpmyadminに直接貼り付けてexplainを追加できる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と一緒に使用して、パラメーターをそれらの値に置き換えます。
これはもちろんコアコードのハックです。私は公共プロジェクトへの貢献に慣れていないので、それをそこに含めたいと思っている人がいたら、気軽にコピーしてください。
QueryBuilderですでに構築されている5つのクエリを使用して、requeteユニオン(DQLまたはQueryBuilderでは不可能)を構築する必要がありました。したがって、これらのクエリを再利用しますが、getParameters()関数を使用すると、指定した順序と同じ順序でパラメーターが指定されるため、問題が発生しました。クエリビルダーを使用する場合の利点の1つは、必要な順序でクエリを作成できることですが、パラメーターを取得するときに、乱雑に取得する可能性があります。これを回避するために、次の関数を作成しました。
$getSqlWithParams = \Closure::bind(function(){
return [$this->getSql(), $this->processParameterMappings($this->_parserResult->getParameterMappings())];
}, null, Query::class);
sQLとソートされたパラメータを取得したいときは:
$getSqlWithParams()->call($query)
\ Doctrine\ORM\Queryステートメントを使用することを忘れないでください。そして、ボイラ!
SQL Serverのプロファイラーを使用して、データベースに送信されているものを取得します。どうやらmySQLのためのいくつかの同様のツールがあります。 MySqlに相当するプロファイラーはありますか?