Saltar al contenido

Solución para «Commands out of sync; you can’t run this command now» en CodeIgniter

Si estás intentando utilizar procedimientos almacenados en tu proyecto de CodeIgniter, seguramente te has topado con este mensaje de error: «Commands out of sync; you can’t run this command now«.

Este mensaje de error (ERROR 2014), devuelve el motor de base de datos MariaDB y/o MySQL por que estás ejecutando dos consultas a la base de datos en simultaneo. Sin embargo, al revisar tu código te das cuenta que no estás ejecutando varias consultas al mismo tiempo.

Este mensaje de error aparece cuando utilizas procedimientos almacenados. El motor de base de datos espera que liberes el conjunto de resultados antes de ejecutar otra consulta. Ahora bien, seguramente si estás almacenando la información utilizando el método result_array(), pero lamentablemente no es suficiente.

Este bug de CodeIgniter sigue existiendo en la última versión disponible, a la fecha del post, estamos hablando de la versión CodeIgniter 3.1. Si googleas sobre este bug encontrarás bastante consultas sobre como solucionar este bug desde hace muchos años.

He visto muchos comentarios, e incluso existen propuestas de solución creando nuestra clase que extienda de la clase CI_DB_mysqli_driver; sin embargo, existe una manera más simple y práctica de resolver este bug.

Veamos un ejemplo. El siguiente código es un método de una clase «X» que quiere obtener de una base de datos la relación de tarjetas de crédito de un cliente. La consulta a la base de datos se hace mediante un procedimiento almacenado.

/**
 * Método que devuelve tarjetas de crédito de un cliente.
 * @author Gonzalo Chacaltana Buleje <[email protected]>
 * @access public
 * @name getCreditCardsByCustomer
 * @version v1.1.8
 * @param string $uuidCustomer UUID de cliente.
 * @return array lista de tarjetas de crédito.
 */
public function getCreditCardsByCustomer(string $uuidCustomer):array
{
	$sp    = "CALL dbxc02cc.sp_getCreditCardsByCustomer(?)";
	$params = array($uuidCustomer);
	$data   = array();
	$query  = $this->db->query($sp, $params);
	if ($query) {
		$data = $query->result_array();
	}
	return $data;
}

Como en todo proyecto, tendrás muchos más métodos que realicen consultas a la base de datos, por lo que al momento de probar tu aplicación, te aparecerá el siguiente mensaje de error.

MySQL Error 2014: Commands out of sync; you can’t run this command now

Para solucionar este bug, deberías de agregar dos métodos luego de almacenar los datos con la función result_array(). Estos métodos se llaman free_result() y next_result(). Veamoslo en el ejemplo.

/**
 * Método que devuelve tarjetas de crédito de un cliente.
 * @author Gonzalo Chacaltana Buleje <[email protected]>
 * @access public
 * @name getCreditCardsByCustomer
 * @version v1.1.8
 * @param string $uuidCustomer UUID de cliente.
 * @return array lista de tarjetas de crédito.
 */
public function getCreditCardsByCustomer(string $uuidCustomer):array
{
	$sp     = "CALL dbxc02cc.sp_getCreditCardsByCustomer(?)";
	$params = array($uuidCustomer);
	$data   = array();
	$query  = $this->db->query($sp, $params);
	if ($query) {
		$data = $query->result_array();
		$query->free_result();
		$query->next_result();
	}
	return $data;
}

Si pruebas el funcionamiento de esté método te saldrá un mensaje de error » Call to undefined method CI_DB_mysqli_result::next_result() «, debido a qué el método next_result() no existe en la clase CI_DB_mysqli_result.

Entonces, debemos de crear ese método, para ello debes abrir el archivo «mysqli_result.php» que se ubica dentro del código fuente del mismo framework. Ruta: «fxci\database\drivers\mysqli«. El nombre «fxci» es el nombre de mi directorio donde tengo el framework de CodeIgniter.

Al final del clase CI_DB_mysqli_result, debemos de agregar el método next_result().

public function next_result()
{
  if (is_object($this->conn_id))
  {
     return mysqli_next_result($this->conn_id);
  }
}

Guardas los cambios y listo para probar. Espero que te haya sido de ayuda. Si tienes otra alternativa de solución para este problema, compártelo en los comentarios.

Publicado enProgramación