sqlite的API可参考:SQLite – C/C++ | 菜鸟教程

sqlite的官网API可参考:Introduction

#include <iostream>
#include <sqlite3.h>
#include <string>// 回调函数,用于查询结果的输出
static int callback(void* data, int argc, char** argv, char** azColName) {// 第一次调用时输出表名static bool firstCall = true;static std::string tableName = reinterpret_cast<const char*>(data);if (firstCall) {std::cout << "\n表名: " << tableName << std::endl;std::cout << "--------------------------------" << std::endl;// 输出列名for (int i = 0; i < argc; i++) {std::cout << azColName[i] << "\t";}std::cout << "\n--------------------------------" << std::endl;firstCall = false;}// 输出数据行for (int i = 0; i < argc; i++) {std::cout << (argv[i] ? argv[i] : "") << "\t";}std::cout << std::endl;return 0;
}int main() {sqlite3* db;char* errMsg = nullptr;int rc;// 1. 打开或创建数据库rc = sqlite3_open("demo.db", &db);if (rc) {std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl;return rc;}std::cout << "成功打开/创建数据库 demo.db" << std::endl;// 2. 创建表const char* createTableSQL ="CREATE TABLE IF NOT EXISTS Users (""ID INTEGER PRIMARY KEY AUTOINCREMENT,""Name TEXT NOT NULL,""Age INTEGER,""Email TEXT UNIQUE NOT NULL);";rc = sqlite3_exec(db, createTableSQL, nullptr, nullptr, &errMsg);printf("%s\n",createTableSQL);if (rc != SQLITE_OK) {std::cerr << "SQL错误: " << errMsg << std::endl;sqlite3_free(errMsg);} else {std::cout << "表 Users 创建成功或已存在" << std::endl;}// 3. 插入数据const char* insertDataSQL ="INSERT INTO Users (Name, Age, Email) VALUES ""('张三', 25, 'zhangsan@example.com'),""('李四', 30, 'lisi@example.com'),""('王五', 28, 'wangwu@example.com');";rc = sqlite3_exec(db, insertDataSQL, nullptr, nullptr, &errMsg);if (rc != SQLITE_OK) {std::cerr << "SQL错误: " << errMsg << std::endl;sqlite3_free(errMsg);} else {std::cout << "成功插入 3 条数据到 Users 表" << std::endl;}// 4. 查询数据std::string tableName = "Users";const char* selectDataSQL = "SELECT * FROM Users;";std::cout << "\n正在查询数据..." << std::endl;rc = sqlite3_exec(db, selectDataSQL, callback, const_cast<char*>(tableName.c_str()), &errMsg);if (rc != SQLITE_OK) {std::cerr << "SQL错误: " << errMsg << std::endl;sqlite3_free(errMsg);}// 5. 关闭数据库sqlite3_close(db);std::cout << "\n数据库连接已关闭" << std::endl;return 0;
}

CMake如下:

cmake_minimum_required(VERSION 3.5)project(testDB LANGUAGES CXX)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)add_executable(testDB main.cpp)
target_link_libraries(testDB sqlite3)

运行结果如下:

sqlite3_exec函数介绍

sqlite3_exec() 是 SQLite C 接口中的一个便捷函数,用于执行一个或多个 SQL 语句,并可选择性地处理查询结果。它是 sqlite3_prepare_v2()sqlite3_step() 和 sqlite3_finalize() 的封装,适合执行不需要复杂处理的 SQL 命令。


函数原型

int sqlite3_exec(
sqlite3 *db, /* 数据库连接对象 */
const char *sql, /* 要执行的 SQL 语句 */
int (*callback)( /* 回调函数,处理查询结果 */
void*, /* 回调函数的第一个参数(由sqlite3_exec的第四个参数传入) */
int, /* 结果行的列数 */
char**, /* 当前行的数据数组 */
char** /* 列名数组 */
),
void *data, /* 传递给回调函数的第一个参数 */
char **errmsg /* 错误信息(需手动释放) */
);

参数详解

1. db
  • 类型sqlite3*
  • 作用: 已打开的数据库连接对象(通过 sqlite3_open() 获得)。
  • 注意: 如果为 `` 或无效连接,函数返回 SQLITE_MISUSE
2. sql
  • 类型const char*
  • 作用: 要执行的 SQL 语句,可以是单个语句或多个语句(用分号 ; 分隔)。
  • 示例:

    sql

    "CREATE TABLE test (id INTEGER); INSERT INTO test VALUES (1);"
  • 注意:
    • 如果 SQL 有语法错误,sqlite3_exec() 会返回错误码,并通过 errmsg 返回错误信息。
    • 不支持参数绑定(如 ? 或 :name),需直接拼接 SQL 字符串(需注意 SQL 注入风险)。
3. callback
  • 类型: 函数指针 int (*callback)(void*, int, char**, char**)
  • 作用: 处理查询结果的回调函数。对 SELECT 查询的每一行结果调用一次;对 INSERT/UPDATE/DELETE 等操作不调用(除非返回影响行数)。
  • 回调函数参数:
    • void* data: 由 sqlite3_exec 的第四个参数 data 传入(通常用于传递上下文)。
    • int argc: 当前行的列数。
    • char** argv: 当前行的数据数组(argv[i] 是第 i 列的值,字符串形式)。
    • char** azColName: 列名数组(azColName[i] 是第 i 列的名称)。
  • 返回值:
    • 返回 0 表示继续处理后续行。
    • 返回非零值会中断查询,sqlite3_exec() 会立即返回 SQLITE_ABORT
  • 示例:
    static int callback(void *data, int argc, char **argv, char **colNames) {
    for (int i = 0; i < argc; i++) {
    printf("%s = %s\n", colNames[i], argv[i] ? argv[i] : "");
    }
    return 0;
    }
4. data
  • 类型void*
  • 作用: 传递给回调函数的第一个参数(callback 的 void* data)。
  • 用途: 通常用于传递上下文信息(如输出文件名、表名等)。
  • 示例:
    const char* tableName = "Users";
    sqlite3_exec(db, "SELECT * FROM Users;", callback, (void*)tableName, &errMsg);
5. errmsg
  • 类型char**
  • 作用: 指向错误信息字符串的指针。如果执行失败,SQLite 会分配错误信息(需手动释放)。
  • 注意:
    • 成功时 *errmsg 为 ``。
    • 失败时需调用 sqlite3_free(*errmsg) 释放内存。
    • 如果传入的 errmsg 为 ``,错误信息不会被返回。
  • 示例:
    char *errMsg = nullptr;
    int rc = sqlite3_exec(db, "INVALID SQL", nullptr, nullptr, &errMsg);
    if (rc != SQLITE_OK) {
    std::cerr << "Error: " << errMsg << std::endl;
    sqlite3_free(errMsg); // 必须释放!
    }

返回值

  • SQLITE_OK (0): 执行成功。
  • 其他错误码(如 SQLITE_ERRORSQLITE_MISUSE): 表示执行失败,可通过 errmsg 获取详情。

典型用法

1. 执行非查询语句(如 CREATE/INSERT)
char *errMsg = nullptr;
int rc = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS test (id INTEGER, name TEXT);"
"INSERT INTO test VALUES (1, 'Alice');",
nullptr, nullptr, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", errMsg);
sqlite3_free(errMsg);
}
2. 执行查询并处理结果
static int printRow(void *unused, int argc, char **argv, char **colNames) {
for (int i = 0; i < argc; i++) {
printf("%s: %s\n", colNames[i], argv[i] ? argv[i] : "");
}
printf("---\n");
return 0;
}
sqlite3_exec(db, "SELECT * FROM test;", printRow, nullptr, &errMsg);

注意事项

  1. SQL 注入风险:
    sqlite3_exec 直接执行 SQL 字符串,避免拼接用户输入。如需参数化查询,应使用 sqlite3_prepare_v2() + sqlite3_bind_*()

  2. 错误处理:
    始终检查返回值,并释放 errmsg(如果非)。

  3. 性能:
    不适合大量数据操作(每次调用会重新解析 SQL)。高频操作建议使用预处理语句(Prepared Statements)。

  4. 多语句执行:
    可通过分号 ; 分隔多个 SQL 语句,但某条语句失败时,后续语句不会执行。


其他函数

如果需要更精细的控制(如参数绑定、事务处理),建议使用:

  1. sqlite3_prepare_v2()
  2. sqlite3_bind_*()
  3. sqlite3_step()
  4. sqlite3_finalize()

例如:

sqlite3_stmt *stmt;
sqlite3_prepare_v2(db, "INSERT INTO test VALUES (?, ?)", -1, &stmt, nullptr);
sqlite3_bind_int(stmt, 1, 2);
sqlite3_bind_text(stmt, 2, "Bob", -1, SQLITE_STATIC);
sqlite3_step(stmt);
sqlite3_finalize(stmt);

sqlite的demo可参考:SQLite3 - Linux C上数据库开发(基本操作,这篇够了)_linux 上c语言使用sqlite3-CSDN博客

Sqlite3小结(小型数据库中增删改查的操作)_如何获得sqlite3库表的记录的大小-CSDN博客

参加上面的连接查看数据代码也可以写成下面代码:

//获取行数int nrow,ncolumn;char selectCmd[]="select * from Users;";char **result;if(sqlite3_get_table(db,selectCmd,&result,&nrow,&ncolumn,&errMsg)!=0){std::cerr << "SQL错误: " << errMsg << std::endl;sqlite3_free(errMsg);}printf("nrow is %d, ncolumn is %d\n",nrow,ncolumn);//测试输出int i,j=0;for(i=1;i<=nrow;i++)//result内结果包含表头信息,因此result[0]是表头信息,实际数据范围为result[1]~result[nrow]{for(j=0;j<ncolumn;j++){printf("%s:%s\n",result[j],result[i*ncolumn+j]);}printf("------------------\n");}

运行结果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/94336.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/94336.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/94336.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

部分CSS笔试题讲解

1. box-sizing: border-box 的作用问题&#xff1a; 默认的 CSS 盒模型 (content-box) 中&#xff0c;元素的 width 和 height 属性只指定了内容区域的尺寸。如果你给元素添加了 padding 或 border&#xff0c;这些值会被加在 width/height 之上&#xff0c;导致元素的实际占用…

雅菲奥朗SRE知识墙分享(二):『SRE对智能运维的升级模型』

SRE深度结合AI创新&#xff0c;雅菲奥朗专家刘峰老师总结了近期人工智能运维领域的突破&#xff0c;合计以下15个关键点:一、领域1&#xff1a;Dev&Ops 深度融合• 关键点1. 组织&#xff1a;Google “SREScale” 最新论文提出「单一故障域 单一 SRE 小组」原则&#xff0…

前端 Promise 全面深入解析

一、Promise基础概念 1、什么是Promise? Promise是一个表示异步操作最终完成或失败的对象。它允许你为异步操作的成功结果和失败原因分别绑定相应的处理方法。 2、Promise的三种状态 pending(等待中): 初始状态,既不是成功,也不是失败 fulfilled(已成功): 操作成功完…

【LIN】2.LIN总线通信机制深度解析:主从架构、五种帧类型与动态调度策略

参考文章&#xff1a; Lin总线通信在STM32作为主机代码以及从机程序 基于STM32的LIN总线的实现 STM32F0-LIN总线通讯程序代码 主从调试OK LIN协议通信DEMO及源码剖析 前文已讲解关于LIN帧代码如何实现&#xff1a;【LIN】1.LIN通信实战&#xff1a;帧收发全流程代码实现 帧类型…

Maven的概念与Maven项目的创建

MavenMaven的概念依赖管理项目构建Maven安装Maven项目的创建Maven的第一个项目Maven的第二个项目Maven的概念 Maven 是 Apache 基金会推出的跨平台的项目管理工具&#xff0c;主要服务于基于Java平台的项目构建、依赖管理和项目信息管理&#xff0c;目前是 Java 生态中最主流的…

Mysql之binlog日志说明及利用binlog日志恢复数据操作记录

众所周知,binlog日志对于mysql数据库来说是十分重要的。在数据丢失的紧急情况下,我们往往会想到用binlog日志功能进行数据恢复(定时全备份+binlog日志恢复增量数据部分),化险为夷! 废话不多说,下面是梳理的binlog日志操作解说: 一、初步了解binlog MySQL的二进制日志…

windows安装Elasticsearch,ik分词器,kibana可视化工具

安装地址 elasticsearch安装地址: Past Releases of Elastic Stack Software | Elastic 分词器下载地址: https://github.com/infinilabs/analysis-ik?tabreadme-ov-file kibana下载地址: Past Releases of Elastic Stack Software | Elastic 注意&#xff1a;版本一定要统…

GaussDB 数据库架构师修炼(十八)SQL引擎-SQL执行流程

1 SQL执行流程查询解析&#xff1a;词法分析、语法分析、 语义分析 查询重写&#xff1a;视图和规则展开、基于规则的查询优化 计划生成&#xff1a;路径搜索和枚举、选出最优执行计划 查询执行&#xff1a;基于优化器生成的物理执行计划对数据进行获取和计算2 解析器和优化器S…

能源管理系统中的物联网数据采集:深度探索与操作指南

一、引言物联网&#xff08;Internet of Things, IoT&#xff09;作为数字化时代的核心基础设施&#xff0c;通过将物理世界的设备、物体与网络连接&#xff0c;实现数据的实时感知与交互。而数据采集作为物联网系统的 “神经末梢”&#xff0c;是整个体系运行的基础。本文将从…

Java实现一个简单的LRU缓存对象

LRU&#xff08;Least Recently Used&#xff09;算法的核心思想是&#xff1a;最近使用的数据将被保留&#xff0c;最久未使用的数据将被淘汰。这种策略适用于内存有限、但又需要高频访问的数据场景&#xff0c;比如缓存系统、页面置换算法等。mysql的缓冲池就是使用的LUR Inn…

整体设计 之定稿 “凝聚式中心点”原型 --整除:智能合约和DBMS的在表层挂接 能/所 依据的深层套接 之2

摘要三“式”三“心”三“物” 整数原型三段式表达 的 凝聚式中心点dot 、组织式核心元素位element和分析式内核基因座locus 三者分别以**“等号线&#xff08;Arc&#xff09;”**&#xff08;动态关联&#xff09;、**“边界线&#xff08;Transition&#xff09;”**&#…

vue.根据url生成二维码

文章目录概要QR码步骤1. 引入库2. 生成二维码3. 将二维码加入页面中用javascript库简化二维码生成1. 引入库2. 使用库生成二维码二维码美化和定制1. 调整大小2. 调整颜色3. 添加自定义形状和图案4. 添加logo性能优化与错误处理1. 减少不必要的计算2. 异步处理概要 生成 URL 二…

WPF+MVVM入门学习

最近在学WPF的MVVM&#xff0c;有两种方式实现&#xff0c;一种是自己实现&#xff0c;一种是借助MVVM框架&#xff0c;接下来通过一个医院自助打印报告机键盘输入界面来演示自己实现、框架CommunityToolkit和Prism的区别。 项目源码&#xff1a;https://gitee.com/cplmlm/Sel…

[e3nn] docs | 不可约表示(Irreps)

链接&#xff1a;https://docs.e3nn.org/en/latest/examples/examples.html docs&#xff1a;e3nn e3nn是一个用于构建欧几里得(E(3))等变神经网络的Python库&#xff0c;这意味着它们能自动保持三维旋转和反射的对称性。 该库使用不可约表示(Irreps)来描述数据变换方式&…

深入浅出 ArrayList:从基础用法到底层原理的全面解析(中)

四、ArrayList 常用方法实战 —— 从添加到遍历的全场景覆盖ArrayList 提供了数十个方法&#xff0c;但日常开发中常用的只有 10 个左右&#xff0c;我们按 “元素操作”“集合查询”“遍历方式” 三类来梳理&#xff0c;每个方法都附带示例和注意事项。4.1 元素添加&#xff1…

java后端如何实现下载功能

后端需要把要下载的若干文件 按 ZIP 格式编码成一段二进制字节流&#xff0c;然后以 Content-Type: application/zip Content-Disposition: attachment; filenamexxx.zip 的形式写进 HTTP 响应体。浏览器收到这段“ZIP 格式的字节流”后&#xff0c;就会弹出保存对话框&#xf…

AI生成技术报告:GaussDB与openGauss的HTAP功能全面对比

GaussDB 与 openGauss 的 HTAP 功能比较 前言 GaussDB集中式版本从505.2版本开始引入了HTAP混合负载功能&#xff0c;openGauss也从7.0.0 RC1版本开始引入了HTAP行列融合功能&#xff0c;加强了行存转列存的使用友好度&#xff0c;但两者的实现似乎存在不小的差异。 虽然文档…

小程序开发指南(四)(UI 框架整合)

✍讲解了微信小程序 UI 框架的使用方法和特点&#xff0c;根据项目需求选择合适的组件库。附有相应的组件库预览码&#xff0c;也是将所有的微信小程序原生组件库整合在一起方便后续开发的使用。如果有不好或者有错误的地方请告知&#xff01;希望可以与大家相互的交流学习&…

golang 1.25.0 安装

wget https://golang.google.cn/dl/go1.25.0.linux-amd64.tar.gz tar -C /usr/local/ -xzf go1.25.0.linux-amd64.tar.gz ln -s /usr/local/go/bin/* /usr/bin/ go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct