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

本文详细介绍了在使用MySQL与C API进行数据库操作时遇到的Commands out of sync错误,解释了其原因及解决方法。通过实例演示了如何正确处理存储结果集与执行命令之间的顺序问题,确保程序顺利执行多条SQL语句。

这个问题出现再 mysql和c  的api。

简单的解决方法是不使用api直接把整个连接和命令传过去。

例如,cmd = 'mysql -h 192.168.32.210 -P 3316 -u bfdroot -pqianfendian -D DMP_GDMP_Cbehe      -e "%s"' % update_sql2

问题原因:

Mysql文档:Commands out of sync

If you get Commands out of sync; you can't run this command now in your client code, you are calling client functions in the wrong order.

This can happen, for example, if you are using mysql_use_result() and try to execute a new query before you have called mysql_free_result(). It can also happen if you try to execute two queries that return data without calling mysql_use_result() or mysql_store_result() in between.

 

第一种 存储结果未释放,然后又查询

第二种两次查询之间没有存储结果



解决方案:

do 

    result = mysql_store_result( mysql ); 
    mysql_free_result(result); 
}while( !mysql_next_result( mysql ) );


例子 http://www.linuxidc.com/Linux/2013-04/82619.htm

 : Update OK!sql: insert into  t_alarm_record_file  (recordPath,recordName,hostIp,startTime,endTime,deviceId,programNumber,deviceType,interfaceNo,alarmType,alarmTime) values ('/figure/data/AlarmRecord/StreamTS/1-码流_魅力音 乐主路/2011-11-07/20111107150116.ts','','10.0.60.2','2011-11-07 15:01:16','1970-01-01 08:00:00',37486602,3905,'0',1,12,'2011-11-07 15:01:20');update  t_alarm  set fileId = LAST_INSERT_ID()  where deviceId = 37486602 and programNumber = 3905 and alarmType = 12 and alarmDate = '2011-11-07 15:01:20' and fileId is null

2011-11-07 15:01:35,331: ERROR  : Update failed!sql: insert into  t_alarm_record_file  (recordPath,recordName,hostIp,startTime,endTime,deviceId,programNumber,deviceType,interfaceNo,alarmType,alarmTime) values ('/figure/data/AlarmRecord/StreamTS/1-码流_魅力音 乐主路/2011-11-07/20111107150116.ts','','10.0.60.2','2011-11-07 15:01:16','1970-01-01 08:00:00',37486602,3905,'0',1,13,'2011-11-07 15:01:27');update  t_alarm  set fileId = LAST_INSERT_ID()  where deviceId = 37486602 and programNumber = 3905 and alarmType = 13 and alarmDate = '2011-11-07 15:01:27' and fileId is null, ERROR:Commands out of sync; you can't run this command now


在第一次调用Update()执行多条sql语句时成功,但以后的所有调用都失败了。
 
经过查找,发现问题在于:在Update()中执行多条sql语句时,

如果仅仅是插入等不需要返回值的SQL语句,也一样得读完整个resault集并释放,最小化的写法:
 
do 

    result = mysql_store_result( mysql ); 
    mysql_free_result(result); 
}while( !mysql_next_result( mysql ) );
 
经过这么一处理,问题终于解决了。



### MySQL 中 `Commands out of sync: You can't run this command now` 的解决方案 在使用 MySQL 客户端(如 C、C++ 或其他语言绑定)执行存储过程或复杂查询时,可能会遇到错误信息:`Commands out of sync: You can't run this command now`。该问题通常出现在连续执行多个语句时,尤其是涉及存储过程、游标或多结果集的情况下。 #### 1. 清空未读取的结果集 MySQL 协议要求客户端必须将所有返回的数据全部读取完毕后,才能继续发送新的命令。如果一个查询(例如调用存储过程)返回了多个结果集,而客户端没有完全读取这些数据,则会引发此错误。 在 Mysql++ 的使用中,当调用存储过程后立即进行 SELECT 查询时,若未清空前一个操作的剩余结果,就会导致“Commands out of sync”异常。解决办法是使用 `Query::store()` 后,确保结果被完全释放,并通过 `Connection::ping()` 或 `Query::reset()` 来同步状态 [^1]。 示例代码如下: ```cpp Query query = conn.query(); query << "CALL my_procedure('param')"; StoreQueryResult result = query.store(); if (!result) { // 处理错误 } // 确保所有结果都被读取并清理 while (conn.more_results()) { conn.read_next_result(); } ``` #### 2. 使用 `CLIENT_MULTI_RESULTS` 标志连接数据库 在建立连接时,如果没有启用多结果支持,也可能导致该错误。应在连接时指定 `CLIENT_MULTI_RESULTS` 标志以允许处理多个结果集。 Mysql++ 初始化连接时可参考以下方式: ```cpp Connection conn(false); conn.set_option(new MultiResultsOption(true)); ``` 或者在底层使用 C API 时设置连接标志: ```c mysql_real_connect(mysql, host, user, pass, db, port, socket, CLIENT_MULTI_RESULTS); ``` #### 3. 避免混合使用非缓冲和缓冲查询 在某些情况下,如果同时使用了非缓冲查询(`use`)和缓冲查询(`store`),而没有正确处理结果集,也会导致同步失败。应统一使用缓冲查询或确保非缓冲查询的结果被完全消费后再发起新请求。 #### 4. 检查存储过程中是否包含隐式提交或事务控制 某些存储过程可能包含 `COMMIT` 或 `ROLLBACK` 语句,这会导致连接状态发生变化,进而影响后续查询。应确保在调用此类存储过程后,重新确认连接处于可用状态。 #### 5. 在 SQL 层面优化存储过程逻辑 如引用中提到的创建函数的例子,若函数内部使用了游标和循环结构,但没有正确关闭游标或释放资源,也可能间接导致客户端出现同步问题。因此,编写存储过程时需注意以下几点: - 显式关闭所有打开的游标; - 确保所有局部变量在退出前完成赋值; - 避免在同一个存储过程中混合多种类型的结果输出; 示例优化后的函数片段如下: ```sql DELIMITER // CREATE FUNCTION GPA(sID CHAR(3)) RETURNS FLOAT READS SQL DATA BEGIN DECLARE state INT DEFAULT 0; DECLARE grade, credit, total_g, total_c, gpa FLOAT DEFAULT 0; DECLARE cursor_ CURSOR FOR ( SELECT Score, CourseCredit FROM Grade JOIN Course ON Grade.CourseID = Course.CourseID WHERE Grade.studentID = sID ); DECLARE CONTINUE HANDLER FOR NOT FOUND SET state = 1; OPEN cursor_; REPEAT FETCH cursor_ INTO grade, credit; IF state = 0 THEN SET total_g = total_g + grade * credit; SET total_c = total_c + credit; END IF; UNTIL state = 1 END REPEAT; CLOSE cursor_; SET gpa = total_g / total_c; RETURN gpa; END // DELIMITER ; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值