Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Por que o mysqli está dando um erro de comandos fora de sincronia?


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.