C语言SQLite取数异常及JSON封装实现网页表格展示求助
SQLite C接口开发问题排查方案
代码查询异常问题根因与修复
根因
你的代码存在3个致命错误:
- 数据库连接提前关闭:打开数据库成功的分支里,直接调用了
sqlite3_close(db),后续所有数据库操作都是在已失效的连接指针上执行,sqlite3_prepare_v2必然返回错误 - 重复释放资源:prepare失败分支、代码末尾各调用了一次
sqlite3_close(db),会触发double free风险 - 错误信息缺失:prepare失败时只打印固定提示,没有输出SQLite返回的具体错误原因,无法快速定位问题;另外代码使用了
exit()/EXIT_FAILURE但未引入<stdlib.h>头文件,会触发编译错误。
修复后的基础查询代码
#include "sqlite3.h" #include <stdio.h> #include <stdlib.h> // 补充缺失的头文件 int main(void) { sqlite3 *db; sqlite3_stmt *stmt; int rc = 0; rc = sqlite3_open("test.db",&db); if(rc != SQLITE_OK) { printf("Database could not be opened %s \n",sqlite3_errmsg(db)); exit(EXIT_FAILURE); } printf("Database sucessful opened\n"); // 移除提前关闭数据库的错误代码 char *sql_stmt = "SELECT * FROM students"; rc = sqlite3_prepare_v2(db, sql_stmt, -1, &stmt, 0); if(rc != SQLITE_OK) { // 打印具体错误信息,不要只输出固定提示 printf("\nUnable to fetch data, error: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return 1; } printf("student records\n"); while(sqlite3_step(stmt) == SQLITE_ROW) { // 注意判断列值是否为NULL,避免空指针崩溃 const unsigned char *col0 = sqlite3_column_text(stmt, 0); const unsigned char *col1 = sqlite3_column_text(stmt, 1); const unsigned char *col2 = sqlite3_column_text(stmt, 2); printf("%s %s %s\n", col0 ? col0 : "NULL", col1 ? col1 : "NULL", col2 ? col2 : "NULL"); } sqlite3_finalize(stmt); sqlite3_close(db); // 所有操作完成后只关闭一次连接 return 0; }
查询结果封装JSON供前端渲染实现方案
两种实现路径,按需选择即可:
方案1:使用SQLite内置JSON函数(无额外依赖,最简便)
SQLite 3.38.0及以上版本内置JSON聚合函数,可以直接在SQL层完成JSON组装,不需要在C代码里做字符串拼接。
核心SQL写法:
-- 把students表所有行组装为JSON数组,每个元素是对应行的JSON对象 SELECT json_group_array( json_object( 'id', id, 'name', name, 'score', score -- 按你的表实际字段名、字段数量补充即可 ) ) AS table_json FROM students;
执行这条SQL后,直接通过sqlite3_column_text(stmt, 0)就能拿到完整的JSON字符串,直接返回给前端HTML页面,用JS解析后渲染表格即可。
方案2:引入轻量JSON库手动组装(兼容旧版本SQLite)
如果你的SQLite版本低于3.38.0,可以引入cJSON这个单文件轻量JSON库(只有cJSON.c、cJSON.h两个文件,直接加入项目编译即可,无额外依赖),逐行遍历结果组装:
核心逻辑代码片段:
// 初始化根JSON数组 cJSON *root = cJSON_CreateArray(); while(sqlite3_step(stmt) == SQLITE_ROW) { cJSON *row = cJSON_CreateObject(); // 逐列添加字段,按你的表结构调整 cJSON_AddStringToObject(row, "id", (const char*)sqlite3_column_text(stmt, 0)); cJSON_AddStringToObject(row, "name", (const char*)sqlite3_column_text(stmt, 1)); cJSON_AddNumberToObject(row, "score", sqlite3_column_int(stmt, 2)); cJSON_AddItemToArray(root, row); } // 拿到最终JSON字符串 char *json_str = cJSON_Print(root); // 使用完json_str后释放内存 cJSON_Delete(root); free(json_str);
拿到json_str后即可返回给前端页面做渲染。
内容的提问来源于stack exchange,提问作者C-3PO
相关产品推荐
相关产品推荐

