Visual studio C++程序内使用Sqlite3

news2024/11/24 0:39:24
Visual studio C++程序内使用Sqlite3

前言

本篇讲解了如何在Visual studio开发的C++桌面应用程序内使用Sqlite数据库,Sqlite的语法和Mysql是一样的,所以本篇文章不对数据库语法做过多介绍,介绍一些常用Sqlite的API


★提高阅读体验★

👉 ♠一级标题 👈

👉 ♥二级标题 👈

👉 ♥ 三级标题 👈

👉 ♥ 四级标题 👈

目录

  • ♠ 引入sqlite
    • ♥ 下载源代码
    • ♥ 复制源码
    • ♥ 打开项目解决方案
    • ♥ 查看所有文件
    • ♥ 包括进项目
    • ♥ 查看新增文件
    • ♥ 不使用预制头
    • ♥ 引用
  • ♠ 查看sqlite文件
  • ♠ 操作数据库
    • ♥ 打开数据库
    • ♥ Sql文本转换
    • ♥ 绑定参数
    • ♥ 执行语句
    • ♥ 重置语句
    • ♥ 获取结果集
    • ♥ 销毁准备语句
    • ♥ 封装执行语句
    • ♥ 关闭数据库连接
  • ♠ 增删改查
    • ♥ 增
    • ♥ 删
    • ♥ 改
    • ♥ 查
  • ♠ 推送
  • ♠ 结语


♠ 引入sqlite

♥ 下载源代码

在这里插入图片描述

传送门:官方下载地址


♥ 复制源码

在这里插入图片描述

将源码复制到我们的工程目录下


♥ 打开项目解决方案

在这里插入图片描述
在这里插入图片描述

默认打开工程就应该有的,右侧没显示去视图内找一下


♥ 查看所有文件

在这里插入图片描述
在这里插入图片描述

选择资源管理器下的展示所有文件,目录会展示我们路径下的所有文件


♥ 包括进项目

在这里插入图片描述

找到我们复制的项目,右键选择包括到项目中即可


♥ 查看新增文件

在这里插入图片描述

再次点击展示所有文件返回之前目录,我们已经可以看到新增的文件了


♥ 不使用预制头

在这里插入图片描述

选择两个c文件,右键选择C/C++ ——> 预编译头,选择不使用预编译头


♥ 引用

在这里插入图片描述

在文件内可以引用我们新增的文件了,目录就是跟目下的路径,没有报错就是引用成功了


♠ 查看sqlite文件

推荐使用工具SQLite Expert Professional功能很强大,不仅能够查看Sqlite数据库文件,还能做增删改查等操作

在这里插入图片描述

传送门:下载地址


♠ 操作数据库

♥ 打开数据库

sqlite3_open接口根据路径名去打开一个sqlite文件,如果不存在则在路径下创建一个,返回的是一个数据库连接对象

  • zFilename : 路径名
  • ppDb:数据库连接对象

在这里插入图片描述

sqlite3_open返回一个int值,SQLITE_OK常量是sqlite3.h里默认声明,返回值等于它即打开成功

  • 演示用例
sqlite3 *db = NULL;

if (sqlite3_open("test.db", &db) == SQLITE_OK) {
    //todo
}

♥ Sql文本转换

sqlite3_prepare接口是解析和编译字符Sql语句,返回值用来判断执行状态和sqlite3_open相同,官方推荐使用sqlite3_prepare_v2新接口

  • db:数据库连接对象
  • zSql:使用UTF-8编码的Sql语句
  • nBytes:表示Sql语句的长度,如果为-1则全部读取zSql
  • ppStmt:指向编译后的数据结构
  • pzTail:如果zSql没有读取完,剩下的会被指向pzTail,pzTail一般是Null

在这里插入图片描述

sqlite3_stmt数据结构就是sqlite3_prepare执行后编译好的Sql语句存储对象

在这里插入图片描述

  • 演示用例
if (sqlite3_prepare_v2(db, sql_createtable, -1, &stmt, NULL) == SQLITE_OK) {
    //todo
}

上述代码通过sqlite3_prepare_v2接口编译了一条Sql语句sql_createtable,编译结果指向了stmt


♥ 绑定参数

sqlite3_bind_XXX接口用用来绑定参数,Sql语句在书写的时候如果需要参数,不会直接书写,而是以?代替,sqlite3_bind_XXX接口的作用就是将参数绑定到一个个问号的位置,类似于格式化字符串

  • 参数1:sqlite3_stmtSql语句编译后的数据结构
  • 参数2:int需要代替的问号位置
  • 参数3:代替问号的值
  • 参数4:有些接口没有,有的有,这里指绑定字节的长度,填-1就是全部读取
  • 参数5:两个选项SQLITE_STATIC指SQLite假定该信息位于静态非托管空间中,不需要释放,SQLITE_TRANSIENT则SQLite会在绑定后返回之前自己创建内存托管,一般使用这个

在这里插入图片描述

在这里插入图片描述

  • 演示用例
sqlite3_bind_text(stmt, 1, key, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, value, -1, SQLITE_TRANSIENT);

上述代码希望通过sql_select声明的Sql 语句向kv表插入数据,插入的key和value用(?,?)代替,通过sqlite3_bind_text函数将希望存储的key和value绑定到了Sql语句的问号处


♥ 执行语句

sqlite3_step接口用来执行编译好的Sql语句,新版本其返回值是SQLITE_ROWSQLITE_DONE两个常量,SQLITE_ROW指当前还有数据没有读取完毕,SQLITE_DONE指Sql语句已经执行完成

  • pStmt:唯一参数指编译后的Sql语句数据结构

在这里插入图片描述

  • 演示用例
if (sqlite3_step(stmt) == SQLITE_DONE) {
    //todo
}

上述代码sqlite3_step执行了存储编译后Sql语句的数据结构stmt


♥ 重置语句

sqlite3_reset语句会把sqlite3_stmt 结构重置到sqlite3_prepare_v2执行后sqlite3_step执行前的状态

  • pStmt:唯一参数就是一个需要被重置的sqlite3_stmt实例

在这里插入图片描述


♥ 获取结果集

sqlite3_column_XXX接口通过在sqlite3_step执行过后,从sqlite3_stmt的实例中获取查询到的结果,多用于查询

  • 参数1:sqlite3_stmt的实例,结果集存储在内
  • 参数2:iCol,查询结果的索引值

在这里插入图片描述

对于不同类型存在不同的结果筛选语句


♥ 销毁准备语句

sqlite3_finalize方法会销回sqlite3_prepare_XX方法创建的sqlite3_stmt实例

  • 参数1:唯一参数为sqlite3_stmt实例

在这里插入图片描述


♥ 封装执行语句

sqlite3_exec语句相当于sqlite3_prepare_v2,sqlite3_step和sqlite3_finalize的封装,简便的同时对应着其效率会更低

  • 参数1:打开的数据库sqlite3实例
  • 参数2:sql的执行局与
  • 参数3:sql执行完的回调函数
  • 参数4:传递给回调函数的指针参数
  • 参数5:错误信息

在这里插入图片描述


♥ 关闭数据库连接

sqlite3_close接口的调用将关闭之前使用sqlite3_open打开的数据库连接,任何与这个连接相关的准备语句必须在调用这个关闭函数之前被释放

  • 参数1:唯一参数为sqlite3数据库连接对象实例

在这里插入图片描述


♠ 增删改查

上述的部分我们已经基本介绍了和操作数据库相关的所有步骤,接下来我们看一下增删改查的演示代码


♥ 增

我们创建一个名为test.db的数据库,并增加名为test_tbl的表

  • 创建数据库文件和表
sqlite3 *db = NULL;

if (sqlite3_open("test.db", &db) == SQLITE_OK) {

   const char *sql_createtable = "CREATE TABLE test_tbl(key TEXT,value TEXT)";
   sqlite3_stmt *stmt = NULL;
   if (sqlite3_prepare_v2(db, sql_createtable, -1, &stmt, NULL) == SQLITE_OK) {

	   if (sqlite3_step(stmt) == SQLITE_DONE) {

		   OutputDebugString(L"create table done");
	   }
	   sqlite3_reset(stmt);
   }
   sqlite3_finalize(stmt);
}
sqlite3_close(db);

在这里插入图片描述
在这里插入图片描述

上述代码我们创建了一个test.db的数据库文件,并创建了一个包含key和value的名为test_tbl的表,从工具内可以看到,目前没有数据

  • 插入数据
sqlite3 *db = NULL;
if (sqlite3_open("test.db", &db) == SQLITE_OK) {

   const char *sql_select = "INSERT INTO test_tbl(key,value) VALUES(?,?)";
   sqlite3_stmt *stmt = NULL;

   if (sqlite3_prepare_v2(db, sql_select, -1, &stmt, NULL) == SQLITE_OK) {

	   sqlite3_bind_text(stmt, 1, "test_key", -1, SQLITE_TRANSIENT);
	   sqlite3_bind_text(stmt, 2, "test_value", -1, SQLITE_TRANSIENT);

	   if (sqlite3_step(stmt) == SQLITE_DONE) {

		   OutputDebugString(L"insert success");
	   }
	   sqlite3_reset(stmt);
   }
   sqlite3_finalize(stmt);
}
sqlite3_close(db);

在这里插入图片描述

上述代码我们插入了一条数据进入到表test_tbl内


♥ 删

sqlite3 *db = NULL;
if (sqlite3_open("test.db", &db) == SQLITE_OK) {

   const char *sql_select = "DELETE FROM test_tbl WHERE key LIKE ?";

   //DELETE FROM test_tbl WHERE key LIKE 'test_key'
   
   sqlite3_stmt *stmt = NULL;

   if (sqlite3_prepare_v2(db, sql_select, -1, &stmt, NULL) == SQLITE_OK) {

	   sqlite3_bind_text(stmt, 1, "test_key", -1, SQLITE_TRANSIENT);

	   if (sqlite3_step(stmt) == SQLITE_DONE) {

		   OutputDebugString(L"delete success");
	   }
	   sqlite3_reset(stmt);
   }
   sqlite3_finalize(stmt);
}
sqlite3_close(db);

在这里插入图片描述

上述代码我们从表test_tbl内删除了key="test_key"的值


♥ 改

sqlite3 *db = NULL;
if (sqlite3_open("test.db", &db) == SQLITE_OK) {

   const char *sql_select = "UPDATE test_tbl SET value =? WHERE key =? ";
   sqlite3_stmt *stmt = NULL;

   if (sqlite3_prepare_v2(db, sql_select, -1, &stmt, NULL) == SQLITE_OK) {

	   sqlite3_bind_text(stmt, 1, "hahahahahahahahahahah", -1, SQLITE_TRANSIENT);
	   sqlite3_bind_text(stmt, 2, "test_key", -1, SQLITE_TRANSIENT);

	   if (sqlite3_step(stmt) == SQLITE_DONE) {

		   OutputDebugString(L"insert success");
	   }
	   sqlite3_reset(stmt);
   }
   sqlite3_finalize(stmt);
}
sqlite3_close(db);

在这里插入图片描述

上述代码我们从表test_tbl内将key=“test_key"的值修改成"hahahahahahahahahahah”


♥ 查

sqlite3 *db = NULL;
if (sqlite3_open("test.db", &db) == SQLITE_OK) {

   const char *sql_select = "SELECT value FROM test_tbl WHERE key=?";
   sqlite3_stmt *stmt = NULL;

   if (sqlite3_prepare_v2(db, sql_select, -1, &stmt, NULL) == SQLITE_OK) {

	   sqlite3_bind_text(stmt, 1, "test_key", -1, SQLITE_TRANSIENT);

	   int ret = sqlite3_step(stmt);
	   if (ret == SQLITE_DONE || ret == SQLITE_ROW) {
		   const char *val = (const char*)sqlite3_column_text(stmt, 0);
	   }
	   sqlite3_reset(stmt);
   }
   sqlite3_finalize(stmt);
}
sqlite3_close(db);

在这里插入图片描述

上述代码我们从表test_tbl内获取了key=“test_key"对应的值”


♠ 推送

  • Github
https://github.com/KingSun5

♠ 结语

若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。
本文属于原创文章,转载请著名作者出处并置顶!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二叉树常见题目

目录 一、判断一棵树是否为另一棵树的子树 二、判断是否对称二叉树 三、翻转二叉树 四、二叉树构建及遍历 五、根据二叉树创建字符串 六、二叉树的最近公共祖先 七、根据前序遍历和中序遍历构造二叉树 八、根据后序遍历和中序遍历构造二叉树 九、二叉树前序非递归…

MySQL——“order by”是如何工作的

假设目前有这么一个表 CREATE TABLE t (id int(11) NOT NULL,city varchar(16) NOT NULL,name varchar(16) NOT NULL,age int(11) NOT NULL,addr varchar(128) DEFAULT NULL,PRIMARY KEY (id),KEY city (city) ) ENGINEInnoDB; 业务要求是要查询城市是“杭州”的所有人名字&a…

1.2计算机系统的层次结构

文章目录(1)微指令(2)汇编语言(3)高级语言(4)操作系统(5)编译程序与解释程序(6)总结请先食用这一篇 计算机工作过程(1&…

考研《数据结构》线性表—顺序表练习题

2.设计一个高效算法&#xff0c;将顺序表L的所有元素逆置&#xff0c;要求算法的空间复杂度为0&#xff08;1&#xff09;。 思路&#xff1a;扫描顺序表L的前半部分元素&#xff0c;对于元素L.data[i]与L.data[len-1-i]对换。 #include<iostream> using namespace std…

XCTF:NewsCenter

一道简单的常规注入题&#xff0c;就当练练手了 尝试’ 直接网页异常&#xff0c;尝试进行闭合# 网页恢复正常&#xff0c;证明SQL语句通过单引号进行闭合&#xff0c;则为字符型注入 直接判断字段数&#xff0c;order by n order by 3#回显正常&#xff0c;order by 4#网页异…

kaggle平台学习复习笔记 | 数据划分与模型集成

目录数据集划分与交叉验证模型集成方法Titanic为例的简单应用kaggle比赛相关tips数据集划分与交叉验证 数据集划分 通常有两种方法&#xff1a; 留出法(Hold-out) 适用于数据量大的情况K折交叉验证(K-fold CV) 适用于数据量一般情况 时间比较长自助采样(Bootstrap) 较少使用 …

Lua C接口编程(二)

引言 上篇文章我们学习了C如何调用Lua&#xff0c;今天我们就来聊聊Lua 如何调用C。 Lua版本&#xff1a;Lua 5.3.5 对于Lua提供的接口有不清楚的&#xff0c;可以参考Lua接口官方文档 一、Lua调用C步骤 需要将C文件编译成动态库在Lua文件中使用package.cpath配置C动态库路…

Linux学习笔记——分布式内存计算Spark安装部署

5.12、分布式内存计算Spark环境部署 5.12.1、简介 Spark是一款分布式内存计算引擎&#xff0c;可以支撑海量数据的分布式计算。 Spark在大数据体系是明星产品&#xff0c;作为最新一代的总和计算引擎&#xff0c;支持离线计算和实时计算。 在大数据领域广泛应用&#xff0c…

虚拟化技术考试重点总结

虚拟化技术考试重点总结 什么是虚拟化&#xff1f;其作用是什么 ​ 虚拟化&#xff0c;是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。可以在一台计算机上同时运行多个逻辑计算机&#xff0c;每个逻辑计算机可运行不同的操作系统&#xff0c;并且应用程序都可以在相互…

Golang中http编程

http介绍 编写web语言&#xff1a; 1.java 2.php&#xff0c;现在都在尝试用go语言编写 3.python&#xff0c;豆瓣 4.go语言 》 beego&#xff0c;gin两个主流的web框架 https协议&#xff1a;我们使用浏览器访问的时候发送的就是http请求 http是应用层的协议&#xff0c;底…

论文投稿指南——中文核心期刊推荐(地质学)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

广告业务系统 之 辅助决策 —— “ AB 实验平台”

文章目录广告业务系统 之 辅助决策 —— “ AB 实验平台”AB 实验平台流量侧 & 渲染侧AB 实验模块架构设计智能流控广告业务系统 之 辅助决策 —— “ AB 实验平台” AB 实验平台 在广告业务中&#xff0c;数据通常作为业务前进的内在驱动力之一。 AB 实验平台就是以实验…

java获取时间并进行计算

前言 SimpleDateFormat使用介绍 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、SimpleDateFormat是什么&#xff1f; 如果你对java源码比较了解。你会发现java对文字&#xff0c;数字的格式化&#xff0c;是有一个公共的父类的Format。 NumberFo…

.Net Core6.0程序发布到IIS支持apk文件下载

ASP.Net Core6.0 WebApi程序发布到IIS支持apk/wgt文件下载 IIS中配置MIME 添加.apk/.wgtapplication/vnd.android.package-archive或application/octet-stream.Net Core6.0 WebApi 程序要在startup.cs中设置 //使用默认文件 app.UseDefaultFiles(); //开启静态文件 app.UseS…

金山区企业工程技术研究中心给予15万元资金奖励

金山区企业工程技术研究中心一、主管部门金山区科学技术委员会二、政策依据《金山区关于进一步鼓励科技创新加快上海科技创新中心重要承载区建设的若干配套政策》&#xff08;金府发〔2020〕3号&#xff09;《金山区关于进一步鼓励科技创新加快上海科技创新中心重要承载区建设的…

赛题发布|“星河杯”隐私计算大赛-赛题发布沙龙成功举办

2023年1月10日下午&#xff0c;由中国信通院与隐私计算联盟主办&#xff0c;中移动信息技术有限公司、联通数字科技有限公司、天翼电子商务有限公司共同协办&#xff0c;FATE开源社区提供技术支持&#xff0c;DataFountain作为官方竞赛平台的“星河杯”隐私计算大赛顺利举办赛题…

Acwing---1212.地宫取宝

地宫取宝1.题目2.基本思想3.代码实现1.题目 X 国王有一个地宫宝库&#xff0c;是 nm 个格子的矩阵&#xff0c;每个格子放一件宝贝&#xff0c;每个宝贝贴着价值标签。 地宫的入口在左上角&#xff0c;出口在右下角。 小明被带到地宫的入口&#xff0c;国王要求他只能向右或…

SAP入门技术分享三:模块化程序

模块化程序1.子程序概要2.子程序定义3.子程序参数&#xff08;1&#xff09;传递参数的方法&#xff08;2&#xff09;定义参数类型&#xff08;3&#xff09;参数与结构体&#xff08;4&#xff09;参数与内表4.调用子程序&#xff08;1&#xff09;调用程序内部子程序&#x…

Android APP 缓存路径

Context.getCacheDir():这个缓存路径打印出来的是&#xff1a;data / data / (APPID ) / cacheAndroid系统中的清除APP缓存清除的就是这个路径: 随着用户手动清空缓存或者APP的卸载&#xff0c;这个路径的缓存也会被删除。请注意&#xff1a;在这个缓存路径上读写是不需要请求文…

Qt扫盲-信号槽理论总结

信号槽理论总结一、概述二、信号槽三、信号四、槽函数五、小例子六、 信号槽的默认参数七、高级使用八、 在Qt 里使用第三方的信号槽一、概述 信号和槽用于对象之间的通信。信号和槽机制是Qt的一个核心特性&#xff0c;也是与其他框架所提供的特性最大不同的部分。Qt的元对象系…