Эта заметка поможет вам найти ошибку в запросах сформированных с помощью библиотеки doctrine2 dbal используемой для языка программирования PHP. Это популярная и качественная библиотека для разработки запросов к базе данных , которая предоставляет удобный API для работы с БД.
В данной заметке речь пойдёт о версии библиотеки doctrine/dbal 2.13.1 и 3.2.
При работе с базой через «query builder» библиотека формирует запрос на «своём языке» этот язык называется DQL (doctrine query lanbuage) который используется в dbal (DataBase Abstraction Layer) и он поддерживает работу с популярными и востребованными SQL базами данных. Затем сфомированный DQL-запрос проверяется на корректность и после этого конвертируется в SQL-запрос конкретной базы данных.
Из этого описания следует что возможны 2 места возникновения ошибки:
- Ошибка в DQL-запросе
- Ошибка в SQL-запросе
1. Ошибка в DQL-запросе
При отладке DQL-запроса логирования внутри сервера БД не поможет, потому что запрос не будет отправлен в БД из за ошибки. Для ошибок в DQL-запросах библиотека формирует исключительную ошибку (Exception) с типом (классом) Doctrine\ORM\Query\QueryException.
Сообщение такой ошибки будет содержать текст[Syntax Error] line {строка}, col {колонка}: Error: {ошибка}
В этом сообщении {строка} и {колонка} будут указывать место в DBAL- запросе где происходит ошибка, а {ошибка} выводит текст ошибки. Например:
[Syntax Error] line 0, col 7: Error: Excepcted T_OPEN_PARETHNESS...
Такая ошибка говорит о том что внутри сформированного запроса встречается оператор или ключевое слово не поддерживаемое DBAL языком.
Чтобы понять в чём ошибка, нужно получить DQL-запрос, для этого можно воспользоваться методом getDQL — и нужно переместиться к указанным координатам ошибки line, col. Если вы используете phpstorm, то можно воспользоваться функцией Naviate → Go to line:column (хоткей для этого Ctrl+G) и ввести 0:7 и вы попадёте в место где произошла ошибка. Проанализируйте это место и исправьте условия формирования этого места.
Помните что ошибки с текстом [Syntax error] выдают координаты места ошибки. После этого они становятся не такими страшными :)
2. Ошибка в SQL-запросе
После того как DQL-запрос пройдёт проверку он будет сконвертирован в SQL и отправлен в базу данных. После того как запрос отправлен — база данных может вернуть ответ с ошибкой, который возник вследствие неверно сформированного SQL-запроса. В таких случаях библиотека doctrine2 dbal вернёт исключительную ошибку, которая будет зависеть от используемой базы данных, а точнее от используемого «драйвера базы данных» (код, который описывает логику работу с конкретной базой данных).
Такие ошибки чаще всего содержать сообщение начинающееся с [SQLSTATE {код-состояния}] An exception occured...
Чтобы отладить эти ошибки можно воспользоваться получением SQL запроса с помощью метода getSQL и проанализировать его. Также можно получить запрос на самом сервере БД, включив логирование запросов.
Где ещё посмотреть запросы?
Если использовать библиотеку совместно с фреймворком symfony, то в режиме отладки для фреймворка включёно логирование всех ошибок в dev.log (в зависимости от того как настроена ротация логов). В этом файле лога ошибки DQL-запросов сохраняются с полным текстом запроса. Поэтому можно не править код вызывая метод getDQL, а просто посмотреть в лог и взять оттуда текст запроса, а затем в нём прыгнуть в координаты line:col в вашем текстовом редакторе. Только DQL пишет line = 0. Нужно иметь ввиду что в некоторых текстовых редакторах (в большинстве) нумерация строк начинается с 1. Т.е если DQL пишет line: 0, col: 1, то прыгать надо в 0:1 адрес.