Pull to refresh

Хранимые процедуры MySQL и «out of sync»

Reading time 1 min
Views 19K
Сегодня очень долго выяснял причину, почему после того как я делаю MySQL запрос, в котором обращаюсь к хранимой процедуре (stored procedure) (PHP 5, MySQL 5, mysqli driver)
CALL procedureName()

то следующий за ним запрос не выполняется, а mysqli_error возвращает ошибку

Error «Commands out of sync; you can't run this command now» number «2014» in query:...

Судя по ошибке, создавалось впечатление, что утеряно соединение. Это и ввело в заблуждение и повело по ложному пути.

Как оказалось, все происходит от того, что моя процедура возвращает результат в виде таблицы, а не единичный результат (число или строка или boolean). Например, результатом вот такого запроса будет таблица:
SELECT * FROM users;

Если хранимая процедура возвращает такую таблицу, то помимо этой таблицы выдается также ещё одно значение — результат выполнения самой процедуры. Такое поведение mysqli драйвера называется множественный результат. Так вот, большинство разработчиков забирает первый и чаще всего единственный результат. В случае же, когда процедура возвращает таблицу, вторичный результат тоже надо вытянуть, иначе буфер результатов останется неочищенным и остальные запросы не пройдут — не смогут туда написать.

В общем случае нужно после того как первый результат забран обычным fetch, сбросить ненужные результаты, вытащив их из буффера:
//$connection — ваш MySQLI объект
while($connection->next_result()) $connection->store_result();

Спасибо человеку под ником Evert, который подсказал ответ на этот вопрос.
Tags:
Hubs:
+4
Comments 15
Comments Comments 15

Articles