我正在使用Symfony 3.4.6 + Doctrine - 这些是我的主要“工具”。
用MySQL编写的两个相同的查询给出了不同的结果。为什么?我不知道。希望有人能帮助我。
首先(工作版):
$connection = $this->getEntityManager()->getConnection();
$result = $connection->fetchAll('
SELECT *
FROM payment_transaction
LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
WHERE payment_transaction.to_id = :user
AND payment_transaction.type IN ("' . implode('", "', $type) . '")
AND payment_transaction.registered_at >= :from
AND payment_transaction.registered_at <= :to
', [
"user" => $user->getId(),
"from" => $from->format("Y-m-d H:i:s"),
"to" => $to->format("Y-m-d H:i:s"),
]);
第二(给出不正确的结果):
$connection = $this->getEntityManager()->getConnection();
$result = $connection->fetchAll('
SELECT *
FROM payment_transaction
LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
WHERE payment_transaction.to_id = :user
AND payment_transaction.type IN (:types)
AND payment_transaction.registered_at >= :from
AND payment_transaction.registered_at <= :to
', [
"user" => $user->getId(),
"from" => $from->format("Y-m-d H:i:s"),
"to" => $to->format("Y-m-d H:i:s"),
"types" => '"' . implode('", "', $type) . '"',
]);
第三(给出不正确的结果):
$connection = $this->getEntityManager()->getConnection();
$result = $connection->fetchAll('
SELECT *
FROM payment_transaction
LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
WHERE payment_transaction.to_id = :user
AND payment_transaction.type IN (:types)
AND payment_transaction.registered_at >= :from
AND payment_transaction.registered_at <= :to
', [
"user" => $user->getId(),
"from" => $from->format("Y-m-d H:i:s"),
"to" => $to->format("Y-m-d H:i:s"),
"types" => "\"" . implode("\", \"", $type) . "\"",
]);
第四次(给出错误 - Array to string conversion
):
$connection = $this->getEntityManager()->getConnection();
$result = $connection->fetchAll('
SELECT *
FROM payment_transaction
LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
WHERE payment_transaction.to_id = :user
AND payment_transaction.type IN (:types)
AND payment_transaction.registered_at >= :from
AND payment_transaction.registered_at <= :to
', [
"user" => $user->getId(),
"from" => $from->format("Y-m-d H:i:s"),
"to" => $to->format("Y-m-d H:i:s"),
"types" => $types,
]);
如果我使用:types
函数生成的结果替换implode
,则第二次和第三次查询工作正常。
问题出在哪里 - IN
? implode
?结合?
谢谢。
更新(22:29)
最新的代码段:
public function history(User $user, \DateTime $from, \DateTime $to,
array $type = [PaymentTransaction::PAYMENT_TRANSACTION_TYPE_SYSTEM,
PaymentTransaction::PAYMENT_TRANSACTION_TYPE_PARTNERSHIP,
PaymentTransaction::PAYMENT_TRANSACTION_TYPE_PERSONAL]): array
{
$connection = $this->getEntityManager()->getConnection();
$result = $connection->fetchAll('
SELECT payment_transaction.*, `user`.`first_name` as `user_first_name`, `user`.`last_name` as `user_last_name`, `user`.`email` as `user_email`
FROM payment_transaction
LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
WHERE payment_transaction.to_id = :user
AND payment_transaction.type IN (:types)
AND payment_transaction.registered_at >= :from
AND payment_transaction.registered_at <= :to
ORDER BY payment_transaction.id DESC
', [
"user" => $user->getId(),
"from" => $from->format("Y-m-d H:i:s"),
"to" => $to->format("Y-m-d H:i:s"),
"types" => $type,
], [
\PDO::PARAM_INT,
\PDO::PARAM_STR,
\PDO::PARAM_STR,
Connection::PARAM_STR_ARRAY,
]);
return $result;
}
它仍然给我一个错误:
' with params [134, ["system"], "2018-02-28 21:24:47", "2018-03-30 21:24:47"]:
Notice: Array to string conversion
更新(22:50)
在用?
符号替换占位符后,查询正在运行。问题仍然存在 - 为什么它不与:name
- 占位符合作?
答案 0 :(得分:1)
'... AND type IN (:types) ...' // sql query
要使用DBAL API对其进行存档,您需要按原样绑定元素数组:
"types" => $types, // $types = ['A', 'B', 'C'] or [1, 2, 3]
传递第三个参数的类型:
Connection::PARAM_STR_ARRAY // or ::PARAM_INT_ARRAY for integer list
示例:
use Doctrine\DBAL\Connection; // don't forget this
// ...
$connection = $this->getEntityManager()->getConnection();
$result = $connection->fetchAll('
SELECT *
FROM payment_transaction
LEFT JOIN `user` ON `user`.`id` = payment_transaction.from_id
WHERE payment_transaction.to_id = :user
AND payment_transaction.type IN (:types)
AND payment_transaction.registered_at >= :from
AND payment_transaction.registered_at <= :to
', [
"user" => $user->getId(),
"from" => $from->format("Y-m-d H:i:s"),
"to" => $to->format("Y-m-d H:i:s"),
"types" => $types,
], [
\PDO::PARAM_INT,
\PDO::PARAM_STR,
\PDO::PARAM_STR,
Connection::PARAM_STR_ARRAY,
]);
答案 1 :(得分:0)
通过将PDO
- 类型替换为DBAL
- 类型来解决。
[
"userId" => $user->getId(),
"types" => $type,
"from" => $from->format("Y-m-d H:i:s"),
"to" => $to->format("Y-m-d H:i:s"),
], [
"userId" => Type::INTEGER,
"types" => Type::SIMPLE_ARRAY,
"from" => Type::STRING,
"to" => Type::STRING,
]
感谢GitHub的Ocramius:https://github.com/doctrine/doctrine2/issues/7166