如何在C++ SQLite中按行而非按列检索表数据?
解决方案
你的代码逻辑存在错误,这是输出不符合预期的核心原因:
- 当前循环顺序是先遍历列,再遍历行:外层循环逐个处理每一列,内层循环通过
sqlite3_step()遍历所有行取出当前列的值,最终导致数据按列聚合输出,而非按行顺序输出。
SQLite没有提供像PostgreSQL PQgetvalue那样直接通过行索引、列索引随机访问数据的函数,它的查询结果采用流式逐行推进的机制:每次调用sqlite3_step()会移动到下一行数据,当返回SQLITE_ROW时,当前行的数据可用,此时可通过sqlite3_column_text()等函数获取当前行中各列的值。
要实现按行顺序输出的需求,需调整循环顺序为先遍历行,再遍历当前行的所有列,修正后的代码如下:
// 用二维向量存储按行组织的数据,更贴合表结构 std::vector<std::vector<std::string>> Sqlite3::get_rows(const std::string& command) { if(!handle) throw std::runtime_error("database is not connected"); sqlite3_stmt * stmt = nullptr; std::vector<std::vector<std::string>> rows; // Prepare (compile) statement if(sqlite3_prepare_v2(handle, command.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { neroshop::print("sqlite3_prepare_v2: " + std::string(sqlite3_errmsg(handle)), 1); return {}; } // Check whether the prepared statement returns no data (for example an UPDATE) if(sqlite3_column_count(stmt) == 0) { neroshop::print("No data found. Be sure to use an appropriate SELECT statement", 1); return {}; } int result = 0; // 逐行推进结果集 while((result = sqlite3_step(stmt)) == SQLITE_ROW) { std::vector<std::string> current_row; // 遍历当前行的所有列 for(int i = 0; i < sqlite3_column_count(stmt); i++) { const char* col_text = reinterpret_cast<const char*>(sqlite3_column_text(stmt, i)); std::cout << col_text << std::endl; current_row.push_back(col_text); } // 行尾添加空行分隔 std::cout << std::endl; rows.push_back(current_row); } if(result != SQLITE_DONE) { neroshop::print("sqlite3_step: " + std::string(sqlite3_errmsg(handle)), 1); } sqlite3_finalize(stmt); return rows; }
如果仍需返回一维向量,可按行的列顺序依次添加元素,但二维向量更适合表示表的行结构,便于后续业务处理。
内容的提问来源于stack exchange,提问作者user20040030
相关产品推荐
相关产品推荐

