На самом деле пост довольно специфический. Начну с описания проблемы, встреченной мной уже минимум два раза. Имеем обычный с виду код выполнения запроса:
$conn = $this->getEntityManager()->getConnection();
$conn->executeQuery($query, [
'param1' => 42,
'param2' => 'forty-two',
'param3' => '%some_other_data%',
]);
При выполнении этого кода ловим ошибку типа такой:
SQLSTATE[08P01]: <<Unknown error>>: 7 ERROR: bind message supplies 0 parameters, but prepared statement "pdo_stmt_000...." requires 3
Казалось бы, что может пойти не так? Мы взяли запрос с именованными параметрами, взяли данные для подстановки и передали всё это в Доктрину. Однако, практика показывает, что при неком специфичном тексте запроса Доктрина не справляется с парсингом текста запроса и считает, что в данном запросе нет именованных параметров. Исходя из моего опыта, такое случалось на запросах с огромным количеством :
, так как именно двоеточие определяет начало именованного параметра.
В качестве запроса, ломающего Доктрину можно привести такой (использую postgresql, текст запроса очень приблизительный):
SELECT
id,
value::FLOAT,
exec_date
FROM (
VALUES
(
8095,
41,
'2020-01-02 10:48:17'
),
--- Таких values тут сотни две
) as vs (id, value, exec_date)
JOIN
some_table t ON vs.id = t.foreign_id::INT
WHERE
t.created_at::TIMESTAMP + interval '3600 second' <= vs.executed_at::TIMESTAMP
AND t.field_one = :param1
AND t.field_two = :param2
--- и еще что-нибудь
Найденное мной быстрое решение - это поменять именованные параметры (:param1
) на позиционные (?
), с такими данными Доктрина успешно справляется. Если есть желание - можете самостоятельно нырнуть в дебри и поковыряться в регулярках, а возможно где-то уже висит issue (но это не точно), или в третьей версии Доктрины это вообще уже исправлено.