MySQL 存储过程导致“Commands out of sync”

MySQL 存储过程导致“Commands out of sync”

在本文中,我们将介绍 MySQL 存储过程导致“Commands out of sync”错误的原因和解决方法。

阅读更多:MySQL 教程

什么是“Commands out of sync”错误

“Commands out of sync”错误是指当您在 MySQL 客户端调用存储过程时,执行一个查询语句后,尝试调用另一个查询语句时,会收到此错误。这是因为第一个查询的结果集还没有完全取出,第二个查询就已经发出了。因此,MySQL 客户端无法正确处理第二个查询请求。

为什么会出现“Commands out of sync”错误

出现“Commands out of sync”错误有两个主要原因:

  1. 存储过程中执行了多个查询语句,并且查询结果集没有完全取出,就尝试调用下一个查询语句。

例如,以下存储过程就会导致此错误:

CREATE PROCEDURE `test`()
BEGIN
    SELECT * FROM `user` WHERE `age` > 20;
    SELECT * FROM `user` WHERE `gender` = 'male';
END

在执行该存储过程时,如果第一条查询的结果集没有完全取出,就会在第二条查询时触发“Commands out of sync”错误。

  1. 存储过程中使用了多个连接。

在MySQL中,每个连接只能在同一时刻处理一条查询语句。如果存储过程中开启了多个连接,并且一个连接还没有处理完毕,就会出现“Commands out of sync”错误。

如何解决“Commands out of sync”错误

解决“Commands out of sync”错误的方法主要有以下三种:

  1. 使用mysqli_multi_query函数。

mysqli_multi_query函数可以在一个 MySQL 客户端调用中执行多个查询语句,并且可以正确处理查询结果集。例如,以下存储过程就可以使用mysqli_multi_query函数执行:

CREATE PROCEDURE `test`()
BEGIN
    SELECT * FROM `user` WHERE `age` > 20;
    SELECT * FROM `user` WHERE `gender` = 'male';
END

PHP 中,您可以使用以下代码来执行该存储过程:

<?php
mysqli = new mysqli('hostname', 'username', 'password', 'database');
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if (mysqli->multi_query("CALL test()")) {
    do {
        if (result =mysqli->store_result()) {
            while (row =result->fetch_row()) {
                printf("%s\n", row[0]);
            }result->free();
        }
    } while (mysqli->next_result());
}mysqli->close();
?>
  1. 在存储过程中关闭查询结果集。

在存储过程中,您可以使用以下代码关闭查询结果集:

SELECT * FROM `user` WHERE `age` > 20;
SELECT * FROM `user` WHERE `gender` = 'male';
SELECT 'done'; # 关闭查询结果集

在 PHP 中,您可以使用以下代码执行该存储过程:

<?php
mysqli = new mysqli('hostname', 'username', 'password', 'database');
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if (mysqli->multi_query("CALL test()")) {
    do {
        if (result =mysqli->store_result()) {
            while (row =result->fetch_row()) {
                printf("%s\n", row[0]);
            }result->free();
        }
    } while (mysqli->more_results() &&mysqli->next_result());

    // 关闭查询结果集
    mysqli->store_result();
}mysqli->close();
?>
  1. 在存储过程中单独处理每个查询语句。

在存储过程中,您可以使用以下代码单独处理每个查询语句:

CREATEPROCEDURE `test`()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE age_cursor CURSOR FOR SELECT * FROM `user` WHERE `age` > 20;
    DECLARE gender_cursor CURSOR FOR SELECT * FROM `user` WHERE `gender` = 'male';

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN age_cursor;
    age_loop: LOOP
        FETCH age_cursor INTO ... # 处理结果集
        IF done THEN
            LEAVE age_loop;
        END IF;
    END LOOP;

    CLOSE age_cursor;

    OPEN gender_cursor;
    gender_loop: LOOP
        FETCH gender_cursor INTO ... # 处理结果集
        IF done THEN
            LEAVE gender_loop;
        END IF;
    END LOOP;

    CLOSE gender_cursor;
END

在 PHP 中,您可以使用以下代码执行该存储过程:

<?php
mysqli = new mysqli('hostname', 'username', 'password', 'database');
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if (mysqli->multi_query("CALL test()")) {
    do {
        if (result =mysqli->store_result()) {
            while (row =result->fetch_row()) {
                printf("%s\n", row[0]);
            }result->free();
        }
    } while (mysqli->more_results() &&mysqli->next_result());
}

$mysqli->close();
?>

总结

“Commands out of sync”错误是 MySQL 存储过程中常见的一种错误。原因是存储过程中执行了多个查询语句或使用了多个连接。解决方法主要有三种:使用mysqli_multi_query函数、在存储过程中关闭查询结果集和在存储过程中单独处理每个查询语句。选取合适的解决方法,可以避免“Commands out of sync”错误的发生,提高 MySQL 存储过程的效率和可靠性。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程