Я использую два подготовленных оператора в PHP / MySQLi для извлечения данных из базы данных mysql. Однако, когда я запускаю инструкции, я получаю сообщение «Команды не синхронизированы, вы не можете запустить команду сейчас».
Вот мой код:
$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();
Что я пробовал:
Используя код:
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
в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
PS: Ошибка «Out of Sync» исходит из «$ stmt1-> ошибки второго оператора»
В mysqli :: query Если вы используете MYSQLI_USE_RESULT, все последующие вызовы возвращают ошибки Команды не синхронизируются, если вы не вызываете mysqli_free_result ()
При вызове нескольких хранимых процедур вы можете выполнить следующую ошибку: «Команды не синхронизированы, вы не можете запустить эту команду сейчас». Это может произойти даже при использовании функции close () в объекте результата между вызовами. Чтобы устранить проблему, не забудьте вызвать функцию next_result () объекта mysqli после каждого вызова хранимой процедуры. См. Пример ниже:
<?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(); ?>
Я надеюсь, это поможет
«Команды не синхронизированы, вы не можете запустить эту команду сейчас»
Подробности об этой ошибке можно найти в документах mysql. Чтение этих деталей дает понять, что результирующие наборы готового исполнения выполнения должны быть полностью загружены до выполнения другого подготовленного оператора в том же соединении.
Устранение проблемы может быть выполнено с помощью вызова результата хранилища. Вот пример того, что я изначально пытался сделать:
<?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); ?>
Приведенное выше приведет к следующей ошибке:
Ошибка описания комментариев: команды не синхронизированы; вы не можете запустить эту команду сейчас
PHP Примечание: неопределенная переменная: post_title в error.php в строке 41 ID: 9033 -> Array ()
Вот что нужно сделать для правильной работы:
<?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); ?>
Несколько вещей, чтобы отметить пример выше:
The bind and fetch on the statement still works correctly. Make sure the results are freed when the processing is done.
Для тех из вас, кто делает правильные вещи и использует хранимые процедуры с подготовленными заявлениями.
По какой-то причине mysqli не может освобождать ресурсы при использовании выходной переменной в качестве параметра хранимой процедуры. Чтобы исправить это, просто верните набор записей внутри тела процедуры вместо сохранения значения в выходной переменной / параметре.
Например, вместо SET outputVar = LAST_INSERT_ID (); вы можете иметь SELECT LAST_INSERT_ID (); Затем в PHP я получаю возвращаемое значение следующим образом:
$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;
Теперь вы готовы выполнить вторую хранимую процедуру, не выполнив ошибку «Команды не синхронизируются, вы не можете запустить команду сейчас». Если вы возвращаете более одного значения в наборе записей, вы можете выполнить цикл и получить все из них следующим образом:
while ($stmt->fetch()) { echo $output_value; }
Если вы возвращаете более одного набора записей из хранимой процедуры (у вас есть несколько выборок), убедитесь, что вы прошли через все эти записи с помощью $ stmt-> next_result ();