【问题标题】:PHP Commands Out of Sync errorPHP 命令不同步错误
【发布时间】:2013-01-11 08:20:45
【问题描述】:

我在 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
    
  • 使用 free_result() 和 mysqli_stmt->close()

PS:“Out of Sync”错误来自第二条语句的“$stmt1->error”

【问题讨论】:

  • +1 一个问得很好的问题。这些天对新用户来说似乎很少见。
  • @BackinaFlash 在写这个问题之前,我实际上看过这个问题。不同之处在于我使用 mysqli_stmt::store_result() 缓冲了我的结果,并在尝试第二条语句之前释放了所有以前的结果
  • 如果你有它,你可以用 MYSQLI_ASYNC 试试,看看它会产生什么输出。此外,您可能想尝试在 mysqli 对象上运行 free_result 而不是语句。
  • 好的。我解决了这个问题。就我而言,我有一个存储过程,它接受输入和输出变量。由于某种原因,当使用输出变量作为存储过程中的参数时,mysqli 无法释放资源。要解决此问题,只需在过程主体内返回一个记录集,而不是将值存储在输出变量/参数中。例如,代替 SET outputVar = LAST_INSERT_ID();你可以有 SELECT LAST_INSERT_ID();

标签: php mysql mysqli


【解决方案1】:

在 mysqli::query 中,如果你使用 MYSQLI_USE_RESULT,所有后续调用都会返回错误 命令不同步,除非你调用 mysqli_free_result()

调用多个存储过程时,您可能会遇到以下错误:“命令不同步;您现在无法运行此命令”。 即使在调用之间对结果对象使用 close() 函数时,也会发生这种情况。 要解决此问题,请记住在每次存储过程调用后对 mysqli 对象调用 next_result() 函数。请参见下面的示例:

<?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();
?>

我希望这会有所帮助

【讨论】:

【解决方案2】:

“命令不同步;您现在无法运行此命令”

有关此错误的详细信息可以在 mysql 文档中找到。阅读这些细节可以清楚地表明,在同一连接上执行另一个准备好的语句之前,需要完全获取准备好的语句执行的结果集。

可以通过使用 store 结果调用来解决问题。这是我最初尝试做的一个示例:

<?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 注意:未定义变量:第 41 行 error.php 中的 post_title 编号:9033 -> 大批 ( )

以下是使其正常工作需要做的事情:

<?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.

【讨论】:

  • 我确实使用了 'store_result()'
  • 我真的不明白为什么,但是按照这个答案所示同时准备两个语句为我修复了 +1
【解决方案3】:

对于那些做正确事情并使用预准备语句的存储过程的人。

由于某种原因,当使用输出变量作为存储过程中的参数时,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(); 遍历所有这些记录集;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-05
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    相关资源
    最近更新 更多