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

如何在C语言中从SQLite表读取数据?代码无法打印查询结果

解决C语言操作SQLite无法打印查询结果的问题

原代码的核心问题

  1. 返回值误用:未捕获sqlite3_step()的返回值,反而一直用sqlite3_prepare_v2()的返回值做判断——而后者成功时返回SQLITE_OK,永远不等于SQLITE_ROW,导致无法进入打印分支。
  2. SQL语句格式错误:查询语句中的换行导致字符串被截断,SQL语句不完整。
  3. 固定次数遍历:用for(int i=0; i<5; i++)固定循环次数,无法适配表中实际行数。
  4. 错误处理遗漏:未检查sqlite3_open()的返回值,且sqlite3_exec()产生的错误信息未释放,会造成内存泄漏。

修正后的代码

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

int main()
{
    char* err = NULL;
    sqlite3* db;
    sqlite3_stmt* stmt;
    
    // 检查数据库打开状态
    int rc = sqlite3_open("DB_test.db", &db);
    if (rc != SQLITE_OK) {
        printf("打开数据库失败: %s\n", sqlite3_errmsg(db));
        return EXIT_FAILURE;
    }

    double x, y, z;
    const char* table = "CREATE TABLE IF NOT EXISTS newCell\
        (id INTEGER PRIMARY KEY AUTOINCREMENT,\
        xCell REAL NOT NULL,\
        yCell REAL,\
        zCell REAL,\
        volume REAL,\
        count INTEGER DEFAULT 1,\
        CONSTRAINT name_unique UNIQUE (xCell,yCell,zCell)\
        );";
    
    rc = sqlite3_exec(db, table, NULL, NULL, &err);
    if (rc != SQLITE_OK) {
        printf("创建表失败: %s\n", err);
        sqlite3_free(err);
        sqlite3_close(db);
        return EXIT_FAILURE;
    }

    // 插入数据(因唯一约束,最终仅插入1条)
    const char* query = "INSERT INTO newCell(xCell,yCell,zCell,volume,count)\
            VALUES(3.8,6.3,4.22,2.112,1)\
            ON CONFLICT(xCell,yCell,zCell) DO UPDATE SET count=count+1";
    for(int i = 0; i < 10; i++){
        rc = sqlite3_exec(db, query, NULL, NULL, &err);
        if(rc != SQLITE_OK){
            printf("插入数据失败: %s\n", err);
            sqlite3_free(err);
            sqlite3_close(db);
            return EXIT_FAILURE;
        }
    }

    // 修复查询语句换行问题,准备查询
    rc = sqlite3_prepare_v2(db, "SELECT xCell,yCell,zCell FROM newCell", -1, &stmt, NULL);
    if(rc != SQLITE_OK){
        printf("准备查询失败: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return EXIT_FAILURE;
    }

    // 遍历所有结果行,直到SQLITE_DONE
    while((rc = sqlite3_step(stmt)) == SQLITE_ROW){
        x = sqlite3_column_double(stmt, 0);
        y = sqlite3_column_double(stmt, 1);
        z = sqlite3_column_double(stmt, 2);
        printf("xCell: %g, yCell: %g, zCell: %g\n", x, y, z);
    }

    // 处理遍历结束后的异常状态
    if(rc != SQLITE_DONE){
        printf("查询失败: %s\n", sqlite3_errmsg(db));
    }

    sqlite3_finalize(stmt);
    sqlite3_close(db);

    return 0;
}

关键修改说明

  • 接收sqlite3_step()的返回值,用while循环遍历所有结果行,直到返回SQLITE_DONE
  • 修复查询语句的换行问题,确保SQL语句完整合法
  • 完善全流程错误处理,覆盖数据库打开、表创建、数据插入、查询准备等环节
  • 释放sqlite3_exec()产生的错误信息,避免内存泄漏
  • 调整循环逻辑,适配表中实际行数(因唯一约束,10次插入最终仅生成1条数据)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:15:56