私のSQLは次のようになります。
$sql = "select * from user where id in (:userId) and status = :status";
$em = $this->getEntityManager();
$stmt = $em->getConnection()->prepare($sql);
$stmt->bindValue(':userId', $accounts, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);
$stmt->bindValue(':status', 'declined');
$stmt->execute();
$result = $stmt->fetchAll();
しかし、それは戻ります:
実行中に例外が発生しました(...)
パラメータあり[[1,2,3,4,5,6,7,8,11,12,13,14]、 "declined"]
注意:配列から文字列への変換
実際のSQLはより複雑であるため、queryBuilder
を使用できません(例:結合された選択、共用体などが含まれます)。
SQL自体が配列をサポートしていないという理由だけで、準備されたステートメントを配列で使用することはできません。これは本当の恥です。行のどこかで、データに3つのアイテムが含まれているかどうかを判断し、IN(?、?、?)を発行する必要があります。 Doctrine ORMエンティティマネージャーがこれを自動的に行います。
幸い、DBALはあなたをカバーしてくれます。 bindまたはprepareを使用しないだけです。マニュアルには例があります: https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#list-of-parameters-変換
あなたの場合、それは次のようになります:
$sql = "select * from user where id in (?) and status = ?";
$values = [$accounts,'declined'];
$types = [Connection::PARAM_INT_ARRAY, \PDO::PARAM_STR];
$stmt = $conn->executeQuery($sql,$values,$types);
$result = $stmt->fetchAll();
上記のコードはテストされていませんが、アイデアを理解する必要があります。 (必ずuse Doctrine\DBAL\Connection;
ために Connection::PARAM_INT_ARRAY
)
名前付きパラメーターを使用する人への注意:
名前付きパラメーター(:param
の代わりに ?
)、型を提供するときはパラメータ名を尊重する必要があります。例えば:
$sql = "select * from user where id in (:accounts) and status = :status";
$values = ['accounts' => $accounts, 'status' => 'declined'];
$types = ['accounts' => Connection::PARAM_INT_ARRAY, 'status' => \PDO::PARAM_STR];
順序が重要ではない_:param
_構文に固執する場合は、少し余分な作業を行う必要がありますが、パラメーターをバインドする簡単な方法を紹介します。
_// store all your parameters in one array
$params = array(
':status' => 'declined'
);
// then, using your arbitrary array of id's ...
$array_of_ids = array(5, 6, 12, 14);
// ... we're going to build an array of corresponding parameter names
$id_params = array();
foreach ($array_of_ids as $i => $id) {
// generate a unique name for this parameter
$name = ":id_$i"; // ":id_0", ":id_1", etc.
// set the value
$params[$name] = $id;
// and keep track of the name
$id_params[] = $name;
}
// next prepare the parameter names for placement in the query string
$id_params = implode(',', $id_params); // ":id_0,:id_1,..."
$sql = "select * from user where id in ($id_params) and status = :status";
_
この場合、次のようになります:"select * from user where id in (:id_0,:id_1,:id_2,:id_3) and status = :status"
_// now prepare your statement like before...
$stmt = $em->getConnection()->prepare($sql);
// ...bind all the params in one go...
$stmt->execute($params);
// ...and get your results!
$result = $stmt->fetchAll();
_
このアプローチは、文字列の配列でも機能します。