O cliente MySQL não permite que você execute uma nova consulta onde ainda existam linhas a serem buscadas de uma consulta em andamento. Consulte Comandos fora de sincronia no documento do MySQL sobre erros comuns.
Você pode usar
mysqli_store_result()
para pré-buscar todas as linhas da consulta externa. Isso os armazenará em buffer no cliente MySQL, portanto, do ponto de vista do servidor, seu aplicativo buscou o conjunto de resultados completo. Em seguida, você pode executar mais consultas, mesmo em um loop de busca de linhas do conjunto de resultados externo agora em buffer. Ou você
mysqli_result::fetch_all()
que retorna o conjunto de resultados completo como um array PHP, e então você pode fazer um loop sobre esse array. Chamar procedimentos armazenados é um caso especial, porque um procedimento armazenado tem o potencial de retornar vários conjuntos de resultados, cada um dos quais pode ter seu próprio conjunto de linhas. É por isso que a resposta de @a1ex07 menciona usando
mysqli_multi_query()
e fazendo um loop até mysqli_next_result()
não tem mais conjuntos de resultados. Isso é necessário para satisfazer o protocolo MySQL, mesmo que no seu caso seu procedimento armazenado tenha um único conjunto de resultados. PS:A propósito, vejo que você está fazendo as consultas aninhadas porque tem dados representando uma hierarquia. Você pode querer considerar armazenar os dados de forma diferente, para que possa consultá-los com mais facilidade. Fiz uma apresentação sobre isso intitulada Modelos para dados hierárquicos com SQL e PHP . Também abordo esse tópico em um capítulo do meu livro SQL Antipatterns:Avoiding the Pitfalls of Database Programação .
Aqui está como implementar
mysqli_next_result()
no CodeIgnitor 3.0.3:Na linha 262 de
system/database/drivers/mysqli/mysqli_driver.php
mudança protected function _execute($sql)
{
return $this->conn_id->query($this->_prep_query($sql));
}
para isso
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;
}
Este tem sido um problema desde 2.x. Acabei de atualizar para 3.xe tive que copiar este hack para a nova versão.