使用MySQL C++ Connector调用存储过程获多结果集遇同步错误
问题描述
用户有一个返回多结果集的MySQL存储过程:
DELIMITER $$ CREATE PROCEDURE sp_getvalues() BEGIN SELECT max(a) FROM A; SELECT max(b1), min(b2) FROM B; SELECT sum(x) FROM C; END $$ DELIMITER ;
使用MySQL C++ Connector调用该存储过程时,已设置CLIENT_MULTI_RESULTS连接选项,第一个结果集能正常获取,但第二次调用pstmt->getResultSet()时触发错误:
Commands out of sync; you can't run this command now
相关调用代码如下:
void test_multiple_query2(Connection* con) { std::unique_ptr< sql::PreparedStatement > pstmt; std::unique_ptr< sql::ResultSet > res; pstmt.reset(con->prepareStatement("CALL sp_getvalues()")); res.reset(pstmt->executeQuery()); if (res->next()) { cout << res->getInt(1) << '\n'; } res.reset(pstmt->getResultSet()); if (res->next()) { cout << res->getInt(1) << '\t' << res->getInt(2) << '\n'; } } int main() { connection_properties["CLIENT_MULTI_RESULTS"]= "true"; connection_properties["hostName"]="tcp://127.0.0.1:3306"; /* user comes from the unit testing framework */ connection_properties["userName"]="testuser"; connection_properties["password"]="mypw"; connection_properties["useTls"]= "true"; Connection* con = driver->connect(connection_properties); test_multiple_query2(con); }
解决方案
要处理多结果集,不能直接连续调用getResultSet(),必须在处理完当前结果集后,调用PreparedStatement的getMoreResults()方法切换到下一个结果集,该方法返回bool值表示是否还有更多结果集。若需自动关闭当前结果集释放资源,可使用getMoreResults(true)(参数为true时会关闭当前结果集)。
修改后的代码示例(循环处理所有结果集):
void test_multiple_query2(Connection* con) { std::unique_ptr<sql::PreparedStatement> pstmt; std::unique_ptr<sql::ResultSet> res; pstmt.reset(con->prepareStatement("CALL sp_getvalues()")); // 执行存储过程,返回是否存在第一个结果集 bool hasResult = pstmt->execute(); while (hasResult) { res.reset(pstmt->getResultSet()); // 处理当前结果集 if (res->next()) { int columnCount = res->getMetaData()->getColumnCount(); for (int i = 1; i <= columnCount; ++i) { if (i > 1) cout << '\t'; cout << res->getInt(i); } cout << '\n'; } // 切换到下一个结果集,同时关闭当前结果集 hasResult = pstmt->getMoreResults(true); } }
关键说明
execute()方法返回true表示当前存在结果集,返回false表示无结果集(可能是执行完毕或返回更新计数)getMoreResults(true)的true参数会自动关闭当前ResultSet,避免资源泄漏,同时完成结果集切换- 必须通过
getMoreResults()确认并切换结果集,直接调用getResultSet()会因前一个结果集未完成状态检查触发"Commands out of sync"错误
内容的提问来源于stack exchange,提问作者Dov
相关产品推荐
相关产品推荐

