query example ejemplos consulta php mysql mysqli

example - Comandos PHP fuera de error de sincronización



mysqli vs mysql (3)

Estoy usando dos declaraciones preparadas en PHP / MySQLi para recuperar datos de una base de datos mysql. Sin embargo, cuando ejecuto las declaraciones, aparece el error "Comandos no sincronizados, no se puede ejecutar el comando ahora".

Aquí está mi código:

$stmt = $mysqli->prepare("SELECT id, username, password, firstname, lastname, salt FROM members WHERE email = ? LIMIT 1"; $stmt->bind_param(''s'', $loweredEmail); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($user_id, $username, $db_password, $firstname, $lastname, $salt); $stmt->fetch(); $stmt->free_result(); $stmt->close(); while($mysqli->more_results()){ $mysqli->next_result(); } $stmt1 = $mysqli->prepare("SELECT privileges FROM delegations WHERE id = ? LIMIT 1"); //This is where the error is generated $stmt1->bind_param(''s'', $user_id); $stmt1->execute(); $stmt1->store_result(); $stmt1->bind_result($privileges); $stmt1->fetch();

Lo que he intentado:

  • Mover las declaraciones preparadas a dos objetos separados.
  • Usando el código:

    while($mysqli->more_results()){ $mysqli->next_result(); } //To make sure that no stray result data is left in buffer between the first //and second statements

  • Utilizando free_result () y mysqli_stmt-> close ()

PD: El error ''Out of Sync'' proviene de la segunda declaración ''$ stmt1-> error''


"Comandos fuera de sincronización; no puede ejecutar este comando ahora"

Los detalles sobre este error se pueden encontrar en los documentos de mysql. La lectura de esos detalles deja en claro que los conjuntos de resultados de una ejecución de declaración preparada deben recuperarse por completo antes de ejecutar otra declaración preparada en la misma conexión.

La solución del problema se puede lograr utilizando la llamada de resultado de la tienda. Aquí hay un ejemplo de lo que inicialmente estaba tratando de hacer:

<?php $db_connection = new mysqli(''127.0.0.1'', ''user'', '''', ''test''); $post_stmt = $db_connection->prepare("select id, title from post where id = 1000"); $comment_stmt = $db_connection->prepare("select user_id from comment where post_id = ?"); if ($post_stmt->execute()) { $post_stmt->bind_result($post_id, $post_title); if ($post_stmt->fetch()) { $comments = array(); $comment_stmt->bind_param(''i'', $post_id); if ($comment_stmt->execute()) { $comment_stmt->bind_result($user_id); while ($comment_stmt->fetch()) { array_push($comments, array(''user_id'' => $user_id)); } } else { printf("Comment statement error: %s/n", $comment_stmt->error); } } } else { printf("Post statement error: %s/n", $post_stmt->error); } $post_stmt->close(); $comment_stmt->close(); $db_connection->close(); printf("ID: %d -> %s/n", $post_id, $post_title); print_r($comments); ?>

Lo anterior dará como resultado el siguiente error:

Error de declaración de comentario: Comandos fuera de sincronización; no puedes ejecutar este comando ahora

Aviso de PHP: Variable no definida: post_title en error.php en la línea 41 ID: 9033 -> Array ()

Esto es lo que se debe hacer para que funcione correctamente:

<?php $db_connection = new mysqli(''127.0.0.1'', ''user'', '''', ''test''); $post_stmt = $db_connection->prepare("select id, title from post where id = 1000"); $comment_stmt = $db_connection->prepare("select user_id from comment where post_id = ?"); if ($post_stmt->execute()) { $post_stmt->store_result(); $post_stmt->bind_result($post_id, $post_title); if ($post_stmt->fetch()) { $comments = array(); $comment_stmt->bind_param(''i'', $post_id); if ($comment_stmt->execute()) { $comment_stmt->bind_result($user_id); while ($comment_stmt->fetch()) { array_push($comments, array(''user_id'' => $user_id)); } } else { printf("Comment statement error: %s/n", $comment_stmt->error); } } $post_stmt->free_result(); } else { printf("Post statement error: %s/n", $post_stmt->error); } $post_stmt->close(); $comment_stmt->close(); $db_connection->close(); printf("ID: %d -> %s/n", $post_id, $post_title); print_r($comments); ?>

Un par de cosas para tener en cuenta sobre el ejemplo anterior:

The bind and fetch on the statement still works correctly. Make sure the results are freed when the processing is done.


En mysqli :: query Si usa MYSQLI_USE_RESULT todas las llamadas subsiguientes devolverán Comandos de error no sincronizados a menos que llame a mysqli_free_result ()

Cuando llame a múltiples procedimientos almacenados, puede ejecutar el siguiente error: "Comandos no sincronizados; no puede ejecutar este comando ahora". Esto puede suceder incluso cuando se usa la función close () en el objeto resultante entre llamadas. Para solucionar el problema, recuerde llamar a la función next_result () en el objeto mysqli después de cada llamada a procedimiento almacenado. Vea el siguiente ejemplo:

<?php // New Connection $db = new mysqli(''localhost'',''user'',''pass'',''database''); // Check for errors if(mysqli_connect_errno()){ echo mysqli_connect_error(); } // 1st Query $result = $db->query("call getUsers()"); if($result){ // Cycle through results while ($row = $result->fetch_object()){ $user_arr[] = $row; } // Free result set $result->close(); $db->next_result(); } // 2nd Query $result = $db->query("call getGroups()"); if($result){ // Cycle through results while ($row = $result->fetch_object()){ $group_arr[] = $row; } // Free result set $result->close(); $db->next_result(); } else echo($db->error); // Close connection $db->close(); ?>

Espero que esto sea de ayuda


Para aquellos de ustedes que hacen lo correcto y usan procedimientos almacenados con declaraciones preparadas.

Por alguna razón, mysqli no puede liberar los recursos cuando usa una variable de salida como parámetro en el proceso almacenado. Para solucionar esto, simplemente devuelva un conjunto de registros dentro del cuerpo del procedimiento en lugar de almacenar el valor en una variable / parámetro de salida.

Por ejemplo, en lugar de tener SET outputVar = LAST_INSERT_ID (); puede tener SELECT LAST_INSERT_ID (); Luego en PHP obtengo el valor devuelto así:

$query= "CALL mysp_Insert_SomeData(?,?)"; $stmt = $mysqli->prepare($query); $stmt->bind_param("is", $input_param_1, $input_param_2); $stmt->execute() or trigger_error($mysqli->error); // trigger_error here is just for troubleshooting, remove when productionizing the code $stmt->store_result(); $stmt->bind_result($output_value); $stmt->fetch(); $stmt->free_result(); $stmt->close(); $mysqli->next_result(); echo $output_value;

Ahora está listo para ejecutar un segundo procedimiento almacenado sin tener el error "Comandos no sincronizados, no puede ejecutar el comando ahora". Si devolvió más de un valor en el conjunto de registros, puede recorrerlos y buscarlos de esta manera:

while ($stmt->fetch()) { echo $output_value; }

Si está devolviendo más de un conjunto de registros desde el proceso almacenado (tiene múltiples selecciones), entonces asegúrese de pasar por todos esos conjuntos de registros usando $ stmt-> next_result ();