VC开发MySql二 (Commands out of sync的解决方案)

本文介绍了解决VC中重复调用MySQL存储过程时遇到Commands out of sync错误的方法。通过循环处理所有结果集确保连接安全复用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

VC重复调用mysql查询接口出现Commands out of sync的解决方案:

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <cstring>
#include <string.h>
#include <atltime.h>
#include <afxdisp.h>
using namespace std;

char* OutErrors(MYSQL* pMySql)
{
	return const_cast<char *>(mysql_error(pMySql));
}
int main(int argc, char* argv[])
{
	try
	{
		//初始化数据
		MYSQL *pMySql = mysql_init((MYSQL*)NULL);
		if (pMySql != NULL)
		{
			//创建连接
			if (mysql_real_connect(pMySql,"ip","user","pass","dbname",3306,NULL,CLIENT_MULTI_STATEMENTS))
			{
				mysql_set_character_set(pMySql,"gb2312");
				for(int i=0; i<5; i++)
				{
					int nvalue = mysql_real_query(pMySql,"call P_SUPPLIER_LOGIN_T('fuxiongjunzlj','3d641b2e4f5dc2b1fb0ab3dff6bc8d92')",(unsigned int)strlen("call P_SUPPLIER_LOGIN_T('fuxiongjunzlj','3d641b2e4f5dc2b1fb0ab3dff6bc8d92')"));
					//int nvalue = mysql_real_query(pMySql,"SELECT * FROM cmsadvice",(unsigned int)strlen("SELECT * FROM cmsadvice"));
					if(nvalue == 0)
					{
						MYSQL_RES *myquery = NULL;
						myquery = mysql_store_result(pMySql);

						MYSQL_FIELD *field;
						//获取字节大小
						int FileNumber = mysql_num_fields(myquery);

						//获取返回名称
						for(int j=0; j<FileNumber; j++)
						{
							field = mysql_fetch_field_direct(myquery,j);
							printf("Field %u is %s \t", j, field->name);
						}
						printf("\n");
						//获取返回值
						MYSQL_ROW record;
						while(record = mysql_fetch_row(myquery))
						{
							for(int k=0; k<FileNumber; k++)
							{
								printf("[%s] \t", record[k]);
							}
						}
						printf("\n");

						mysql_free_result(myquery);//标记1

						while ((mysql_next_result(pMySql)) != 0)//在这里加一个循环即可解决无法重复调用的问题 标记2
						{ 
							mysql_free_result(myquery); 
						} 
						printf("查询成功... \n");
					}
					else
					{
						printf("查询异常:%s \n",OutErrors(pMySql));
					}
				}
			}
			else
			{
				//输出异常信息
				OutErrors(pMySql);
				return false;
			}
		}
	}
	catch(...)
	{
		return 0;
	}
}
也就是标记1的地方正常释放但有可能在释放的时候存储过程返回的记录集有可能没有完成 当使用当前连接进行下一次调用存储过程时mysql内部的处理是自动pass掉的,也是情有可原的.知道这里的原因,增加标记2处的处理即可解决问题
其实我们一般只用mysql_query、mysql_use_result等几个函数,问题的症结在于当执行一个存储过程的时候, 数据库返回的是多个数据集合,即使只有一个数据集合,他也会有一个空集合用于结束一次回话,作者骂他变态,其实不然,可能作者考虑到的只是一般的请 求,mysql是给所有用户使用的,说不能真有变态的人把图片文件等等直接保存在mysql字段里面,那么回复就不可能一次完成,需要多此网络交互,那么 所有的交互肯定需要一个结束符号,并且存储过程本来就可以返回多个数据集合,如果他在c pai中只做一个结果己处理就允许下一次全新的请求,那么对于同一连接,在mysql服务断其实还有没有发送完成的数据,这个时候他安全的做法就是不接受 任何新的请求,直到数据发送完全,或者连接关闭,不然,mysql协议解析就会出现问题,下次发送就会出现黏包或者丢包,所以他的做法是完全正确的,即使 只有一个结果集合,也需要当前会话内的通讯(比如mysql_next_result)确认完毕,然后结束本次请求,这个时候服务端其实没有数据了,但是 这个过程是不能省略的,然后在不关闭连接的情况下就可以进行全新的请求了。 
所以总结起来就是:使用存储过程的时候一定要循环执行,把所有的结果集合都取到,直到为空,这个时候当前数据库连接才可以安全归还回去.


参考文章:http://www.jb51.net/article/27085.htm


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑的大象

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值