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

Commands out of sync; you can't run this command now

提问人:Joshxtothe4 提问时间:3/5/2009 最后编辑:Peter O.Joshxtothe4 更新时间:7/30/2023 访问量:279083

问:

我正在尝试执行我的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;
        }
    }
}

我试过阅读这篇文章,但我不确定该怎么做。我已经阅读了有关商店结果和免费结果的信息,但是这些在使用它们时没有区别。我不确定这个错误到底是什么时候导致的,我想知道为什么会引起它,以及如何解决它。

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

php sql mysql mysqli

评论


答:

0赞 Paul Tomblin 3/5/2009 #1

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

另一种可能性是,您正在从一段时间循环获取的中间返回。你永远无法完成外部获取。

评论

1赞 3/5/2009
如果我$con全局化(这是不好的做法,但应该按照您的描述工作),我仍然有同样的错误。
1赞 Mathieu J. 5/30/2019
我不认为拥有全球联系是不好的做法
136赞 user42092 3/5/2009 #2

您不能同时进行两个查询,因为 mysqli 默认使用无缓冲查询(对于准备好的语句;对于 vanilla 则相反)。您可以将第一个获取到数组中并遍历该数组,或者告诉mysqli缓冲查询(使用$stmt->store_result())。mysql_query

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

评论

4赞 3/5/2009
我同意,mysqli 有点脑残。不过,它确实对PDO mysql驱动程序做了正确的事情。
20赞 Shadow 3/14/2013
您可以同时进行两个查询 - 您只需要运行我认为您的响应应该更清楚。$stmt->store_result();
4赞 n34_panda 6/7/2014
我花了很长时间才找到这些信息 - 它不容易显示。谢谢。我只是将我的查询分开以拆分它们(不是同时的,而是程序性的$select_stmt->close();
1赞 alfadog67 12/7/2016
您可以同时创建 2 个连接,并在每个连接上创建一个无缓冲的预准备语句,而不会出现同步错误。
1赞 lucaferrario 1/29/2018
我知道这看起来很奇怪,但是我在执行查询时遇到了这个错误,mysqli_query违反了外键......因此,如果这种情况发生在任何人身上,请仔细检查您的 INSERT 查询是否没有违反任何外键
1赞 staticsan 3/6/2009 #3

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

您的解决方案是修改算法,这样您就不需要同时进行这两个算法,或者将它们更改为使用缓冲查询,这可能是它们在 C 库中存在的原始原因之一(另一个是提供一种游标)。

评论

1赞 3/6/2009
我不需要同时进行这两项工作,我很高兴 countQuery 在我的第二次查询之前完全完成,但我不确定如何阻止 countQuery 处于 proggress 状态
0赞 staticsan 3/9/2009
您没有从 countQuery 中检索任何数据,这就是它仍在“进行中”的原因。检索所有行,或将其更改为 SELECT COUNT(ARTICLE_NO) 并获取该行。然后,将运行第二个查询。
0赞 Pacerier 6/30/2015
当您说“异步MySQL API”时,您指的是哪个API?另外,我没有得到你的结论。这个“问题”可以得到解决,而不需要异步的 API。
1赞 staticsan 6/30/2015
老实说@Pacerier我也不确定我的意思了!在MySQL连接的六年中发生了很多事情,因此我认为我所指的任何东西都可能已被重命名和/或合并到其他一些新驱动程序中。
42赞 tracy.brown 12/1/2009 #4

我在我的 C 应用程序中解决了这个问题 - 这是我是如何做到的:

  1. 引用mysql论坛:

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

  2. 在运行查询并处理结果 [C API: ] 后,我循环访问通过多个 SQL 语句执行(例如两个或多个 select 语句)发生的任何可能挂起的结果(背靠背不处理结果)。mysql_store_result()

    事实是,我的过程不会返回多个结果,但数据库在我执行之前并不知道:[C API: ]。我在循环中执行此操作(为了更好地衡量),直到它返回非零。这时,当前连接处理程序知道可以执行另一个查询(我缓存处理程序以最大程度地减少连接开销)。mysql_next_result()

    这是我使用的循环:

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

我不了解 PHP,但我相信它有类似的东西。

评论

13赞 Josh 4/24/2012
这就是我的。在PHP中,我刚刚添加了:while(mysqli_next_result($con));
0赞 Chen Xie 10/13/2012
感谢您的答案解决了我的问题。我删除了分隔符,它可以工作。我没有释放(获取)或存储我的结果,而是关闭光标并在完成一个查询语句后重新构建。
0赞 Pacerier 4/20/2015
@Josh,如何在旧版扩展中做到这一点?mysql
1赞 Genome 2/16/2018
删除查询末尾的分号修复了“命令不同步;你现在不能运行这个命令“问题,当使用Python MySQLdb。
3赞 Norman 9/13/2012 #5

我使用CodeIgniter。 一台服务器OK ...这个可能更老了...... 无论如何使用

$this->db->reconnect();

修复了它。

评论

8赞 Jeremy J Starcher 9/22/2012
这如何解决这个问题?
4赞 Pacerier 6/30/2015
@Norman,这并不能“解决”问题。它只是通过丢弃整个连接并再次重新连接来避免它。从性能的角度来看,这根本没有意义。
4赞 Nader Ben Mabrouk 10/28/2014 #6

要解决此问题,您必须在使用前存储结果数据

$numRecords->execute();

$numRecords->store_result();

就这样

19赞 stalin beltran 2/21/2015 #7

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

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

评论

0赞 Richard 6/27/2016
这一点很重要:存储过程返回的结果集高于 SP 中的代码可能生成的任何结果集。您必须处理该错误,否则会出现以下错误:stackoverflow.com/a/2315229/4495850
0赞 Mixtelf 4/5/2015 #8

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

0赞 mech 8/16/2016 #9

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

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

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

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

19赞 Juergen Schulze 9/12/2016 #10

在使用 $mysqli->query 之前,我每次都会调用此函数,它也适用于存储过程。

function clearStoredResults(){
    global $mysqli;
    
    do {
         if ($res = $mysqli->store_result()) {
           $res->free();
         }
    } while ($mysqli->more_results() && $mysqli->next_result());        
    
}
0赞 Kazmi 3/5/2018 #11

清除引用内存,并运行下一个 MYSQL fetch

如果使用 或 result set 获取数据,则首先必须在获取所有数据后从内存中清除获取的数据。因为在清除获取的内存之前,您不能在同一连接上执行另一个 MYSQL 过程。BufferedUnbuffered

在脚本的右末添加以下函数,这样就可以解决问题了

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

PHP 文档中的参考

评论

1赞 Your Common Sense 3/5/2018
如果你不需要一些记录,那么你一开始就不应该选择它们。与其只是释放它们,不如根本不选择它们。如果不是这种情况,并且您获取了所有选定的记录,那么也根本不会有这样的错误,也不需要调用 close() 或 free()。至于存储过程,还有一种不那么野蛮的方法,如上面的答案所述
0赞 mickmackusa 2/7/2021
@Kaz 我在那本手册上没有看到任何推荐.method(); or method()
1赞 Ari Waisberg 3/7/2018 #12

这是我的问题!!

参数绑定是“动态的”,所以我有一个变量来设置数据的参数以使用bind_param。所以那个变量是错误的,但它没有抛出像“错误的参数数据”这样的错误,而是说“不同步 bla bla bla”,所以我很困惑......

0赞 fabpico 3/25/2019 #13

我在使用 Doctrine DBAL QueryBuilder 时遇到了这个错误。

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

我的解决方案是在没有 QueryBuilder 的情况下编写子选择。

-1赞 Mahad Ali 5/4/2019 #14

我的问题是我首先使用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 语句之后,正在启动一套全新的查询系统;我还通过以下方式添加这些文件和其他内容

评论

0赞 Mahad Ali 5/4/2019
get_category.php(此处使用 prepare 语句)pastebin.com/BiWysdYz admin_get_category_body.php(此处为 mysqli) pastebin.com/Pwm30icm 注意:由于限制,无法发布所有代码
0赞 Mahad Ali 5/4/2019
我刚刚想到的事情是,我还再次通过全局$connection添加连接变量;所以我认为基本上在以 mysqli_stmt_close($stmt) 结束 prepare 语句之后,正在启动一套全新的查询系统;而且我正在通过include添加这些文件和其他东西。
10赞 ice 6/1/2019 #15

使用后

stmt->execute();

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

stmt->close();

这个问题困扰了我几个小时。希望它能解决你的问题。

评论

2赞 Jay Dadhania 10/10/2019
关闭语句不是必需的。正如上面@stalinbeltran回答的那样,我们需要在准备另一个语句之前“消耗”一个语句的结果。所以,会给出这个错误,但可以正常工作。$stmt1->execute(); $stmt2=$conn->prepare(...)$stmt1->execute(); $result1=$stmt1->get_result(); $stmt2=$conn->prepare(...)
1赞 Abhinash Majhi 8/20/2020
兄弟,它帮了我,谢谢你。如果每个说这个和那个的人,我在关闭第一个之前使用了mysqli_prepare两次。它有效。
-3赞 Janaka Bandara 9/12/2019 #16

创建两个连接,分别使用两个连接

$mysqli = new mysqli("localhost", "Admin", "dilhdk", "SMS");

$conn = new mysqli("localhost", "Admin", "dilhdk", "SMS"); 

评论

1赞 David G. 11/19/2019 #17

另一个原因: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);

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

0赞 Teemo 4/7/2020 #18

我正在使用 ODBC,此修复程序对我有用: ODBC ->选项卡 系统DSN ->双击配置我的数据源 ->详细信息 ->选项卡 游标 -> 取消选中 [不缓存只进游标的结果] ->单击确定

-1赞 shelbypereira 6/8/2020 #19

这是一个老问题,但发布的答案在我的情况下都不起作用,我发现在我的情况下,我在存储过程中对一个表进行了选择和更新,同一个表有一个更新触发器,该触发器正在被触发并将过程发送到无限循环中。一旦发现错误,错误就消失了。

0赞 Nikkorian 7/16/2020 #20

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

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

1赞 Isac 10/24/2020 #21

仅供参考,我在混合两者并在同一代码中遇到了这个问题:multi_queryquery

$connection->multi_query($query);
...
$connection->query($otherQuery);

对于我所读到的内容,未使用的结果待处理,因此导致了上述错误。

我用一个循环解决了它,该循环消耗了以下所有结果:multi_query

$connection->multi_query($query);
while ($connection->next_result()); // <--- solves the problem
...
$connection->query($otherQuery);

就我而言,where 中的所有查询都插入了,所以我对结果本身不感兴趣。multi_query

-2赞 Ing. Jordan García 12/22/2021 #22

此错误的最终解决方案如下:

1) 必须将此代码复制并粘贴到存储过程的下一个查询上方。

do if($result=mysqli_store_result($myconnection)){ mysqli_free_result($result); } while(mysqli_more_results($myconnection) && mysqli_next_result($myconnection));

评论

1赞 Community 12/22/2021
正如目前所写的那样,你的答案尚不清楚。请编辑以添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以在帮助中心找到有关如何写出好答案的更多信息。
0赞 Willt42 3/19/2022 #23

我在收集完第一个查询的结果后放置了这一行代码。为我工作

mysqli_next_result($connection);
-2赞 Saad Ahmad 7/30/2023 #24
<?php
$getData = $db->query("CALL `pet_sitter_list`()");
while ($row = mysqli_fetch_object($getData)): ?>
 your data fetching ...
<?php endwhile; 
$getData->close();
$db->next_result();
?>

像这样,您可以毫无问题地调用另一个查询。

评论

0赞 Your Common Sense 7/30/2023
请不要添加抄袭其他答案的答案
0赞 Community 8/4/2023
正如目前所写的那样,你的答案尚不清楚。请编辑以添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以在帮助中心找到有关如何写出好答案的更多信息。