You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过C/C++ sqlite3接口遍历查询返回行的各字段值

问题根源

你遇到的现象由两个问题共同导致:

  1. 数组下标越界:回调函数的argv参数是从0开始索引的,你写的cout << argv[1];属于越界访问。当前你程序读到的VERTEX表查询结果只有1列,有效下标只有0,越界读刚好拿到了相邻内存里存储的相同字符串"ale",所以才会重复输出两次"ale"。
  2. 数据库连接错误:你代码里用相对路径打开test.db,程序实际连接的是运行时工作目录下的数据库文件,和你预期存了多列数据的数据库不是同一个文件,所以读到的表只有1列1行数据,自然没法拆分多列值。
sqlite3_exec回调参数说明

要正确取单行内的每个字段值,先明确回调四个入参的含义:

  • argc:当前结果行的列总数
  • azColName:字符串数组,长度与argc一致,按顺序存储每一列的列名
  • argv:字符串数组,长度与argc一致,按顺序存储当前行每一列的字段值,注意argv数组下标从0开始;如果字段值为NULL,对应位置的指针为空
  • 第一个void*类型参数:是你调用sqlite3_exec时传入的第4个参数,用于透传自定义数据,传0时无实际作用
  • 回调返回0时会继续处理下一行结果,返回非0值会直接中断查询
修正代码

修正后的回调函数

补全空值判断,去掉越界访问的代码:

static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
    cout << "===== 单行数据分割线 =====" << endl;
    for (int i = 0; i < argc; i++)
    {
        const char* val = argv[i] ? argv[i] : "NULL";
        cout << azColName[i] << " = " << val << endl;
    }
    return 0;
}

修正后的查询函数

补全数据库连接校验、关闭逻辑,建议用绝对路径指定数据库文件避免连错:

void retrieve_vertex_from_db()
{
    sqlite3 *db;
    // 替换为你的数据库文件实际绝对路径
    int ret = sqlite3_open("/your/actual/path/test.db", &db);
    if (ret != SQLITE_OK)
    {
        cerr << "数据库打开失败: " << sqlite3_errmsg(db) << endl;
        sqlite3_close(db);
        return;
    }
    string sql = "SELECT * FROM VERTEX;";
    char *errMsg = nullptr;
    ret = sqlite3_exec(db, sql.c_str(), callback, nullptr, &errMsg);
    if (ret != SQLITE_OK)
    {
        cerr << "查询执行失败: " << errMsg << endl;
        sqlite3_free(errMsg);
    }
    else
    {
        cout << "查询执行成功" << endl;
    }
    sqlite3_close(db);
}
排查指引

如果修正后仍读不到多列数据,按以下步骤排查:

  • 打开程序实际连接的数据库文件,执行.schema VERTEX确认表结构,执行SELECT * FROM VERTEX;确认表内实际存储的数据,和你预期的多列数据是否一致
  • 检查之前插入数据的逻辑,确认是否给所有列都插入了有效值
  • 运行程序前确认当前工作目录,避免读到其他路径下的旧版本test.db文件

内容的提问来源于stack exchange,提问作者Alejandro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:54:20