命令不同步;您现在不能运行此命令


94

我正在尝试执行PHP代码,该代码通过mysqli调用两个MySQL查询,并得到错误“命令不同步;您现在不能运行此命令”。

这是我正在使用的代码

<?php
$con = mysqli_connect("localhost", "user", "password", "db");
if (!$con) {
    echo "Can't connect to MySQL Server. Errorcode: %s\n". Mysqli_connect_error();
    exit;
}
$con->query("SET NAMES 'utf8'");
$brand ="o";
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE % ? %";
if ($numRecords = $con->prepare($countQuery)) {
    $numRecords->bind_param("s", $brand);
    $numRecords->execute();
    $data = $con->query($countQuery) or die(print_r($con->error));
    $rowcount = $data->num_rows;
    $rows = getRowsByArticleSearch("test", "Auctions", " ");
    $last = ceil($rowcount/$page_rows);
}  else {

print_r($con->error);
}
foreach ($rows as $row) {
    $pk = $row['ARTICLE_NO'];
    echo '<tr>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['USERNAME'].'</a></td>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['shortDate'].'</a></td>' . "\n";
    echo '<td><a href="#" onclick="deleterec(\'Layer2\', \'' . $pk . '\')">DELETE RECORD</a></td>' . "\n";
    echo '</tr>' . "\n";
}
function getRowsByArticleSearch($searchString, $table, $max) {
    $con = mysqli_connect("localhost", "user", "password", "db");
    $recordsQuery = "SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME, date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y' ) AS shortDate FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE '%?%' ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s')" . $max;
    if ($getRecords = $con->prepare($recordsQuery)) {
        $getRecords->bind_param("s", $searchString);
        $getRecords->execute();
        $getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate);
        while ($getRecords->fetch()) {
            $result = $con->query($recordsQuery);
            $rows = array();
            while($row = $result->fetch_assoc()) {
                $rows[] = $row;
            }
            return $rows;
        }
    }
}

我已经尝试阅读此书,但不确定该怎么做。我已经阅读了有关存储结果和免费结果的信息,但是使用它们时并没有什么区别。我不确定此错误的确切原因,并想知道其原因以及如何解决。

按照我的调试语句,由于我的sql语法near附近,甚至没有输入countQuery的第一个if循环'% ? %'。但是,如果我只是选择*而不是尝试根据LIKE子句进行限制,则仍然会出现命令不同步错误。

Answers:


115

您不能同时进行两个查询,因为mysqli默认情况下使用无缓冲查询(对于预准备语句;对于vanilla则相反mysql_query)。您可以将第一个取入数组并循环遍历,也可以告诉mysqli缓冲查询(使用$stmt->store_result())。

有关详细信息,请参见此处


3
我同意,mysqli有点大脑损坏。不过,它确实可以通过PDO mysql驱动程序执行正确的操作。

17
可以同时进行两个查询-您只需要运行即可,$stmt->store_result();我认为您的回答应该更清楚。
2013年

3
我花了很长时间才找到此信息-没有容易显示的信息。谢谢。我只是将查询与 $select_stmt->close();它们分开(不是同时进行的,而是过程性的
n34_panda 2014年

@flussence,您已声明“ mysqli默认情况下使用无缓冲查询”。那么我们如何将其设置为其他方式呢?
Pacerier

1
我知道这看起来很奇怪,但是在执行mysqli_query违反外键的查询时遇到了此错误...因此,如果任何人都遇到这种情况,请仔细检查您的INSERT查询是否没有违反任何外键
lucaferrario,2016年

33

我在C应用程序中解决了这个问题-这是我的方法:

  1. 从mysql论坛报价:

    当您在应用程序内部使用分号分隔符终止查询时,将导致此错误。从命令行或在查询浏览器中执行查询时,需要使用分号分隔符来终止查询,但请在应用程序内部的查询中删除该分隔符。

  2. 在运行查询并处理结果[C API:mysql_store_result()]之后,我遍历了通过多个SQL语句执行(例如两个或多个select语句)而产生的任何其他潜在的未决结果(不处理结果而背对背)。

    事实是,我的过程不会返回多个结果,但是直到执行以下代码,数据库才知道:[C API:mysql_next_result()]。我会循环执行(很好的措施),直到返回非零值为止。那是当前的连接处理程序知道可以执行另一个查询的时候(我缓存我的处理程序以最大程度地减少连接开销)。

    这是我使用的循环:

    for(; mysql_next_result(mysql_handler) == 0;) 
      /* do nothing */;
    

我不知道PHP,但是我敢肯定它也有类似的东西。


11
这是给我的。在PHP中,我刚刚添加了:while(mysqli_next_result($ con));
乔什(Josh)

感谢您解决我的问题的答案。我删除了定界符,它可以工作。我没有释放(获取)或存储结果,而是在完成一条查询语句后关闭游标并重新构建。

@Josh,如何做到这一点在传统的mysql延伸?
Pacerier,2015年

1
使用Python MySQLdb时,在查询末尾删除分号可解决“命令不同步;您现在不能运行此命令”的问题。
Genome '18

17

今天,我遇到了同样的问题,但仅限于使用存储过程时。这使查询的行为类似于多查询,因此在进行另一个查询之前,您需要“消费”其他可用结果。

while($this->mysql->more_results()){
    $this->mysql->next_result();
    $this->mysql->use_result();
}

这一点很重要:存储过程返回的结果集超出了SP中代码可能生成的任何结果集。您必须处理该错误或遇到以下错误:stackoverflow.com/a/2315229/4495850
理查德(Richard)

11

在每次使用$ mysqli-> query以及存储过程时,我每次都会调用此函数。

function clearStoredResults(){
    global $mysqli;

    do {
         if ($res = $mysqli->store_result()) {
           $res->free();
         }
        } while ($mysqli->more_results() && $mysqli->next_result());        

}

5

一旦使用

stmt->execute();

可以关闭它以使用另一个查询。

stmt->close();

这个问题困扰着我几个小时。希望它将解决您的问题。


1
无需关闭语句。正如@stalinbeltran在上面回答的那样,我们需要在准备另一个语句之前先“使用”该语句的结果。因此,$stmt1->execute(); $stmt2=$conn->prepare(...)会出现此错误,但效果$stmt1->execute(); $result1=$stmt1->get_result(); $stmt2=$conn->prepare(...)很好。
杰伊·达德尼亚

兄弟帮我谢谢你。如果每个人都这么说,那我在关闭第一个之前就使用mysqli_prepare两次。有用。
Abhinash Majhi

2

我使用CodeIgniter。一台服务器可以...这台服务器可能更旧...无论如何使用

$this->db->reconnect();

解决它。


7
如何解决这个问题?
杰里米·J·斯塔彻

4
@Norman,这不能“解决”问题。它只是通过丢弃整个连接并再次重新连接来避免这种情况。从性能的角度来看,这根本没有任何意义。
Pacerier,2015年

1

问题是MySQL客户端C库,大多数MySQL API都建立在该库上。问题在于C库不支持同时执行查询,因此在此之上构建的所有API也不支持。即使您使用无缓冲查询。这是编写异步MySQL API的原因之一。它使用TCP直接与MySQL服务器通信,并且有线协议确实支持同时查询。

您的解决方案是修改算法以使您不必一次进行两个操作,或者将它们更改为使用缓冲的查询,这可能是C库中存在它们的最初原因之一(另一个是提供一种游标)。


1
我不需要同时进行两个操作,我很高兴countQuery在第二个查询之前完全完成,但是我不确定如何停止countQuery的进展

您没有从countQuery检索任何数据,这就是为什么它仍在“进行中”的原因。检索所有行,或将其更改为SELECT COUNT(ARTICLE_NO)并获取该行。然后,您的第二个查询将运行。
staticsan

当您说“异步MySQL API”时,您指的是哪个API?另外,我没有得到您的结论。可以解决此“问题”,而无需使API异步。
Pacerier,2015年

1
老实说@Pacerier我也不完全明白我的意思了!六年来,MySQL连接发生了很多事情,因此我以为我所指的任何内容都可能被重命名和/或合并到其他一些新驱动程序中。
staticsan 2015年


1

另一个原因:store_result()不能被调用两次。

例如,在下面的代码中,错误5被打印。

<?php

$db = new mysqli("localhost", "something", "something", "something");

$stmt = $db->stmt_init();
if ($stmt->error) printf("Error 1 : %s\n", $stmt->error);

$stmt->prepare("select 1");
if ($stmt->error) printf("Error 2 : %s\n", $stmt->error);

$stmt->execute();
if ($stmt->error) printf("Error 3 : %s\n", $stmt->error);

$stmt->store_result();
if ($stmt->error) printf("Error 4 : %s\n", $stmt->error);

$stmt->store_result();
if ($stmt->error) printf("Error 5 : %s\n", $stmt->error);

(这可能与原始示例代码无关,但可能与寻求该错误答案的人员有关。)


1

这是我的问题!!!

参数绑定是“动态的”,因此我有一个变量来设置数据的参数,以便使用bind_param。因此,该变量是错误的,但没有抛出“错误的参数数据”之类的错误,而是说“不同步bla bla bla”,所以我很困惑。


0

我认为问题在于您正在函数中建立一个新连接,然后没有在最后关闭它。您为什么不尝试传递现有连接并重新使用它呢?

另一种可能性是您正在退出while循环获取的中间。您永远不会完成外部获取。


1
如果我将$ con设置为全局(这是一种不好的做法,但是应该按照您的描述运行),我仍然遇到相同的错误。

1
我认为建立全球联系不是坏习惯
Mathieu J.

0

检查是否正确输入了所有参数。如果定义并传递给函数的参数数量不同,则会引发相同的错误。


0

这与最初的问题无关,但是我有相同的错误消息,并且该线程是Google的第一个命中对象,我花了一段时间才弄清楚问题是什么,所以它可能对其他人有用:

我没有使用mysqli,仍然使用mysql_connect,我有一些简单的查询,但是一个查询导致所有其他查询在同一Connection中失败。

我使用mysql 5.7和php 5.6,我有一个数据类型为“ JSON”的表。显然,我的php版本无法识别mysql的返回值(php只是不知道如何处理JSON格式,因为内置的mysql模块太旧了(至少我认为))

现在,我将JSON-Field-Type更改为Text(就目前而言,我不需要本机mysql JSON-功能),并且一切正常


0

如果您使用Buffered或Unbuffered结果集来获取数据,则首先必须在获取所有数据后简单地从内存中清除获取的数据。由于您无法在同一连接上执行另一个MYSQL过程,直到您清除获取的内存。在脚本的函数右边添加以下内容,这样可以解决问题

$numRecords->close(); or $numRecords->free(); // This clears the referencing memory, and will be ready for the next MYSQL fetch

PHP文档中的参考


1
如果您不需要一些记录,那么您不应该首先选择它们。除了完全释放它们外,根本不要选择它们。如果不是这种情况,并且您获取了所有选定的记录,那么也将根本没有这样的错误,也不需要调用close()或free()。从存储过程开始,上面的答案中介绍了一种更少野蛮的方法
您的常识

0

我使用Doctrine DBAL QueryBuilder遇到了此错误。

我使用QueryBuilder创建了一个查询,该查询使用列子选择,也使用QueryBuilder创建了列。子选择仅通过创建$queryBuilder->getSQL(),而不执行。创建第二个子选择时发生错误。通过$queryBuilder->execute()在使用之前临时执行每个子选择$queryBuilder->getSQL(),一切正常。$queryBuilder->connection尽管每个子选择上都有新的QueryBuilder实例,但在执行当前准备的SQL之前,连接似乎仍处于无效状态,无法创建新的SQL。

我的解决方案是在不使用QueryBuilder的情况下编写子选择。


0

我正在使用ODBC,并且该修复程序对我有用:ODBC->选项卡System DSN->双击以配置我的数据源->详细信息->选项卡游标-> 取消选中 [不缓存仅向前游标的结果]- >单击确定


0

我经常遇到此错误,并且总是在运行存储过程时才在phpmyadmin或SQL Workbench中调试(我正在使用mysqli进行php连接)。

错误是由于调试涉及在代码中的关键位置插入SELECT语句以告知变量状态等事实而导致的。运行在这些客户端环境中产生多个结果集的存储过程可以,但是会产生“从php调用时,“命令不同步”错误。解决方案始终是注释掉或删除调试选择,因此该过程只有一个结果集。


-1

我的问题是,我先使用prepare语句,然后在同一页面上使用mysqli查询,并收到错误消息“命令不同步;您现在不能运行此命令”。仅当我使用具有prepare语句的代码时,才出现错误。

我要做的是结束这个问题。而且有效。

mysqli_stmt_close($ stmt);

我的密码

get_category.php(此处使用prepare语句)

    <?php


    global $connection;
    $cat_to_delete =    mysqli_real_escape_string($connection, $_GET['get'] );

    $sql = "SELECT category_name FROM categories WHERE category_id = ? ;";


    $stmt = mysqli_stmt_init($connection);

    if (!mysqli_stmt_prepare($stmt, $sql))
        $_SESSION['error'] = "Error at preaparing for deleting query. mysqli_stmt_error($stmt) ." & redirect('../error.php');

    mysqli_stmt_bind_param($stmt, 's', $cat_to_delete);

    if (!mysqli_stmt_execute($stmt))
        $_SESSION['error'] = "ERror at executing delete category ".mysqli_stmt_error($stmt) &
            redirect('../error.php');


    mysqli_stmt_bind_result($stmt, $cat_name);

    if (!mysqli_stmt_fetch($stmt)) {
        mysqli_stmt_error($stmt);
    }



    mysqli_stmt_free_result($stmt);
    mysqli_stmt_close($stmt);

admin_get_category_body.php(此处为mysqli)

        <?php

        if (isset($_GET['get']) && !empty($_GET['get']) )
        {
            include 'intodb/edit_category.php';
        }


        if (check_method('get') && isset($_GET['delete']) )
        {
            require 'intodb/delete_category.php';
        }


        if (check_method('get') && isset($_GET['get']) )
        {
            require 'intodb/get_category.php';
        }


        ?>

        <!--            start: cat body          -->

        <div     class="columns is-mobile is-centered is-vcentered">
            <div class="column is-half">
                <div   class="section has-background-white-ter box ">


                    <div class="has-text-centered column    " >
                        <h4 class="title is-4">Ctegories</h4>
                    </div>

                    <div class="column " >


                        <?php if (check_method('get') && isset($_GET['get'])) {?>
                        <form action="" method="post">
                            <?php } else {?>
                            <form action="intodb/add_category.php" method="post">
                                <?php } ?>

                                <label class="label" for="admin_add_category_bar">Add Category</label>
                                <div class="field is-grouped">

                                    <p class="control is-expanded">

                                        <?php if (check_method('get') && isset($_GET['get'])) {?>

                                            <input id="admin_add_category_bar" name="admin_add_category_bar_edit" class="input" type="text" placeholder="Add Your Category Here" value="<?php echo $cat_name; ?>">

                                            <?php


                                            ?>
                                        <?php } else {?>
                                            <input id="admin_add_category_bar" name="admin_add_category_bar" class="input" type="text" placeholder="Add Your Category Here">

                                        <?php } ?>
                                    </p>
                                    <p class="control">
                                        <input type="submit" name="admin_add_category_submit" class="button is-info my_fucking_hover_right_arrow" value="Add Category">
                                    </p>
                                </div>
                            </form>


                            <div class="">

                                <!--            start: body for all posts inside admin          -->


                                <table class="table is-bordered">
                                    <thead>
                                    <tr>
                                        <th><p>Category Name</p></th>
                                        <th><p>Edit</p></th>
                                        <th><p>Delete</p></th>
                                    </tr>
                                    </thead>

                                    <?php

                                    global $connection;
                                    $sql = "SELECT * FROM categories ;";

                                    $result = mysqli_query($connection, $sql);
                                    if (!$result) {
                                        echo mysqli_error($connection);
                                    }
                                    while($row = mysqli_fetch_assoc($result))
                                    {
                                        ?>
                                        <tbody>
                                        <tr>
                                            <td><p><?php echo $row['category_name']?></p></td>
                                            <td>
                                                <a href="admin_category.php?get=<?php echo $row['category_id']; ?>" class="button is-info my_fucking_hover_right_arrow" >Edit</a>

                                            </td>

                                            <td>
                                                <a href="admin_category.php?delete=<?php echo $row['category_id']; ?>" class="button is-danger my_fucking_hover_right_arrow" >Delete</a>

                                            </td>
                                        </tr>


                                        </tbody>
                                    <?php }?>
                                </table>

                                <!--           end: body for all posts inside admin             -->




                            </div>

                    </div>
                </div>


            </div>

        </div>
        </div>

我刚想到的是,我还通过全局$ connection;再次添加了连接变量。因此,我认为在以mysqli_stmt_close($ stmt);结束prepare语句之后,基本上会启动一套全新的查询系统;而且我正在通过包含添加这些文件和其他东西


get_category.php(此处使用prepare语句)pastebin.com/BiWysdYz admin_get_category_body.php(此处mysqli) pastebin.com/Pwm30icm 注意:由于限制,无法发布所有代码
Mahad Ali,

我刚想到的是,我再次通过全局$ connection;添加连接变量。因此,我认为在以mysqli_stmt_close($ stmt);结束prepare语句之后,基本上会启动一套全新的查询系统;而且我正在通过包含添加这些文件和其他内容。
Mahad Ali

-1

这是一个老问题,但是对于我来说,所有发布的答案均不起作用,我发现在我的情况下,我对存储过程中的一个表进行了选择和更新,同一表具有一个更新触发器,该触发器被触发并指示程序陷入无限循环。一旦发现错误,错误就会消失。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.