Клиент MySQL не позволяет вам выполнить новый запрос, если все еще есть строки, которые должны быть извлечены из текущего запроса. См. Команды не синхронизированы в документе MySQL по распространенным ошибкам.
Вы можете использовать mysqli_store_result()
для предварительной выборки всех строк из внешнего запроса. Это буферизует их в клиенте MySQL, поэтому с точки зрения сервера ваше приложение получило полный набор результатов. Затем вы можете выполнить больше запросов даже в цикле выборки строк из буферизованного внешнего набора результатов.
Или вы mysqli_result::fetch_all()
, который возвращает полный набор результатов в виде массива PHP, а затем вы можете выполнить цикл по этому массиву.
Вызов хранимых процедур является особым случаем, потому что хранимая процедура может возвращать несколько результирующих наборов, каждый из которых может иметь свой собственный набор строк. Вот почему в ответе @ a1ex07 упоминается использование mysqli_multi_query()
и цикл до тех пор, пока у mysqli_next_result()
больше не будет наборов результатов. Это необходимо для удовлетворения протокола MySQL, даже если в вашем случае ваша хранимая процедура имеет один набор результатов.
PS: Кстати, я вижу, что вы делаете вложенные запросы, потому что у вас есть данные, представляющие иерархию. Возможно, вы захотите сохранить данные по-другому, чтобы вам было проще их запрашивать. Я сделал презентацию об этом под названием Модели для иерархических данных с SQL и PHP . Я также освещаю эту тему в главе моей книги Антипаттерны SQL: предотвращение ловушек программирования баз данных .
Вот как реализовать mysqli_next_result()
в CodeIgnitor 3.0.3:
В строке 262 из system/database/drivers/mysqli/mysqli_driver.php
изменить
protected function _execute($sql)
{
return $this->conn_id->query($this->_prep_query($sql));
}
к этому
protected function _execute($sql)
{
$results = $this->conn_id->query($this->_prep_query($sql));
@mysqli_next_result($this->conn_id); // Fix 'command out of sync' error
return $results;
}
Эта проблема возникает с 2.x. Я только что обновился до 3.x и мне пришлось скопировать этот хак в новую версию.