【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
目录
- 一、前言
- 二、SQL介绍
- 三、如何在 Windows 上安装 SQLite
- 3.1 下载预编译的二进制文件
- 3.2 添加环境变量
- 四、如何使用C/C++ API连接SQLite
- 五、使用DEVCPP链接SQLite数据库
- 5.1 编译静态SQLite3数据库文件
- 5.2 建立静态库的测试项目
- 六、总结
- 七、参考
一、前言
正如题目所言,最近笔者需要完成一个数据库嵌入式编程
的任务,要求使用C/C++
编程语言,由于笔者用不习惯Visual Studio
系列软件,遂选用DEV-CPP
作为开发工具,由于之前没有相关经验,踩了许多坑,特此记录SQLite+DEV-CPP实现C/C++嵌入式编程操作数据库过程。
二、SQL介绍
SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。SQLite 的一个重要的特性是零配置的,这意味着不需要复杂的安装或管理。
三、如何在 Windows 上安装 SQLite
3.1 下载预编译的二进制文件
- 访问SQLite下载页面 ,从 Windows 区下载预编译的二进制文件。
- 需要下载 sqlite-tools-win32-*.zip 和 sqlite-dll-win32-*.zip 和sqlite-amalgamation-3380500.zip 。
共三个压缩文件。 - 创建文件夹
C:\sqlite
,并在此文件夹下解压上面三个压缩文件,将文件夹内所有文件放到C:\sqlite
目录下,得到sqlite3.def
、sqlite3.dll
和sqlite3.exe
等文件如下。
3.2 添加环境变量
- 添加
C:\sqlite
到PATH
环境变量。
- 最后打开
cmd
,使用sqlite3
命令,将显示如下结果。
至此sqlite安装成功。
四、如何使用C/C++ API连接SQLite
基础的三个API如下表。
序号 | API |
---|---|
1 | sqlite3_open(const char *filename, sqlite3 **ppDb) |
2 | sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg) |
3 | sqlite3_close(sqlite3*) |
sqlite3_open(const char *filename, sqlite3 **ppDb)
该例程打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。如果 filename 参数是 NULL 或 ‘:memory:’,那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。如果文件名 filename 不为 NULL,那么 sqlite3_open() 将使用这个参数值尝试打开数据库文件。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开。sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)
该例程提供了一个执行 SQL 命令的快捷方式,SQL 命令由 sql 参数提供,可以由多个 SQL 命令组成。在这里,第一个参数 sqlite3 是打开的数据库对象,sqlite_callback 是一个回调,data 作为其第一个参数,errmsg 将被返回用来获取程序生成的任何错误。sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。sqlite3_close(sqlite3*)
该例程关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。
但是我们要怎样使用DEVCPP链接到SQLite数据库呢?下一章将会详细描述。
五、使用DEVCPP链接SQLite数据库
5.1 编译静态SQLite3数据库文件
前文3.2节中我们已经下载了SQLite
的预编译的二进制文件。
接下来我们编译sqlite3静态库。打开DEV-CPP
,新建一个静态链接库项目sqlite_lib
。我们把项目保存在一个我们事先建好的文件夹中,文件夹路径C:\sqlite\sqlite_lib
。如下图:
新建项目结束后,我们将源代码中的sqlit3.h
以及sqlite3.c
文件拷贝至C:\sqlite\sqlite_lib
文件夹内。如下图:
然后在DEV-CPP
中的项目上右键,添加sqlite_lib
文件夹内的两个名为sqlite3
文件。
之后,我们点击编译按钮或者运行菜单中的编译菜单或者直接按F9,开始编译。可以看到编译成功,并生成了sqlite_lib.a
静态库。
恭喜,至此距离链接成功已经仅差一次成功的测试了。
5.2 建立静态库的测试项目
测试官网给出的测试代码是否能正常编译并正常工作。我们在DEV-CPP
中新建一个控制台项目。项目保存在文件夹路径C:\sqlite\sqlite_lib_demo
。见下图:
我们将官网的示例代码粘贴到main.c
文件中。该代码的作用是打开test.db
数据库,如果没有该数据库,则创建一个新的。代码如下:
#include <stdio.h>
#include <sqlite3.h>
int main(int argc, char* argv[])
{sqlite3 *db;char *zErrMsg = 0;int rc;rc = sqlite3_open("test.db", &db);if( rc ){fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));exit(0);}else{fprintf(stderr, "Opened database successfully\n");}sqlite3_close(db);
}
同时,我们将C:\sqlite\sqlite_lib
文件夹中的sqlite3.h
以及刚生成的sqlite_lib.a
拷贝至C:\sqlite\sqlite_lib_demo
文件夹中。
这里注意拷贝文件的后缀,不要拷贝错了。
注意:
即使将静态链接库文件拷贝至C:\sqlite\sqlite_lib_demo
文件夹内,但是DEV-CPP
编译时不会自动将静态库链接到项目里,需要手动再做一步告诉DEV-CPP链接什么库到项目里。
需要:
点击DEVCPP上项目菜单,项目属性。打开项目选项窗口,切换到参数标签。
点击加入库或者对象,选择上文拷贝过的sqlite_lib.a
,然后依次点击打开确定按钮。
最后:
我们来编译项目。
嗯?弹出了一个错误。提示没有sqlite3.h这个文件或目录
。
将#include <sqlite3.h>
改为#include "sqlite3.h"
即可。
再次点击运行,此时提示打开数据库成功
。
检查文件夹C:\sqlite\sqlite_lib_demo
,出现了test
数据库。
呼~终于成了。
后续给出了一些嵌入式编程练习,笔者也写了一个非常简单的交互式操作数据库的程序,仅为了测试。
题目:
- 创建一个数据库Test,里面增加一个表格Student(Sno int, Sname char(10), Ssex char(2), Sbirth date)。
- 编写一个C/C++程序,一个简单的界面,通过界面接口,向表中插入10条记录,通过接口实现对数据库的增删改查操作(举例就行)。
创建一个数据库Test,里面增加一个表格Student(Sno int, Sname char(10), Ssex char(2), Sbirth date)。
这里我们使用命令行进入C:\sqlite\sqlite_lib_demo文件架,使用命令创建一个表格并使用“.schema Student”查看该表详细信息。
上面的命令将在当前目录下创建一个文件 testDB.db
。该文件将被 SQLite 引擎用作数据库。如果您已经注意到 sqlite3 命令在成功创建数据库文件之后,将提供一个 sqlite>
提示符。一旦数据库被创建,您就可以使用 SQLite 的 .databases
命令来检查它是否在数据库列表中。
cd C:\sqlite\sqlite_lib_demosqlite3 Student.dbCREATE TABLE Student(Sno INT PRIMARY KEY NOT NULL,Sname CHAR(10),Ssex CHAR(2),Sbirth DATE);.schema
编写一个C/C++程序,一个简单的界面,通过界面接口,向表中插入10条记录,通过接口实现对数据库的增删改查操作(举例就行)。
前文中我们已经使用DEV-CPP
连接到了SQLite
数据库,这里编写代码实现交互式操作SQLite数据库。
将如下代码拷贝至main.c
。通过界面接口向表中插入10条记录。
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"int haveInfo=0;static int callback(void *NotUsed, int argc, char **argv, char **azColName){int i;if(argc>0){for(i=0; i<argc; i++){int j;if(strlen(azColName[i])%2==0){ //中文for(j=0;j<strlen(azColName[i]) && \strlen(azColName[i])%2==0;j+=2){printf("%c%c",azColName[i][j],azColName[i][j+1]);} } else{for(j=0;j<strlen(azColName[i]);j++){printf("%c",azColName[i][j]);} } printf(" = ");char * arg = argv[i] ? argv[i] : "NULL";if(strlen(arg)%2==0){ //中文for(j=0;j<strlen(arg);j+=2){printf("%c%c",arg[j],arg[j+1]);} } else{for(j=0;j<strlen(arg);j++){printf("%c",arg[j]);} } printf("\n");}haveInfo=1;}return 0;
}int main(int argc, char* argv[])
{sqlite3 *db;char *zErrMsg = 0;int rc;char *sql;/* Open database */rc = sqlite3_open("Student.db", &db);if( rc ){fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));exit(0);}else{fprintf(stderr, "Opened database successfully\n");}system("color 3");int func=99;while(1){if(func==99){printf("**********C语言连接sqlite数据操作***********\n" \"1.查询\n" \"2.插入\n" \"3.删除\n" \"4.修改\n" \"5.查询Course表\n"\"6.查询某个学生选修某一门课程的选课信息\n"\"0.退出\n" \"*********C语言连接sqlite数据操作***********\n" \"请选择你需要的操作: ");}scanf("%d",&func);if(func!=0 && func!=1 && func!=2 && func!=3 && func!=4 && func!=5 && func!=6){func=99;}if(func==1){int num=-1;while(num==-1){printf("请输入查询表Student中的记录次数:"); scanf("%d",&num);} int i;for(i=0;i<num;i++){printf("输入查询表Student中的记录的学号," \"仅支持学号查询,例002:\n"); // SELECT * FROM Student WHERE Sno=02;int Sno;char SQL[500];scanf("%d",&Sno);
// printf("----%d %s %s %s----\n",Sno);snprintf(SQL, 500, "SELECT * FROM Student WHERE Sno=%d;",Sno);
// printf("正在执行2:%s\n",SQL);/* Execute SQL statement */rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);if( rc != SQLITE_OK ){ fprintf(stderr, "查询失败,SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{if(haveInfo){fprintf(stdout, "查询成功,信息如上↑\n");haveInfo=0;}else{fprintf(stdout, "查询成功,未查询到相关信息\n");}}} printf("执行完毕,进入主菜单\n"); func=99;}if(func==2){int num=-1;while(num==-1){printf("请输入插入至表Student中的记录条数(仅限数字):"); scanf("%d",&num);} int i;for(i=0;i<num;i++){printf("请按格式输入插入的每一条记录内容,格式:学号 姓名 "\"性别 生日,例\"001 贾明一 男 2000-10-10\"\n"); // INSERT INTO Student VALUES(002,'的','男','2000-10-10');int Sno;char Sname[10],Ssex[2],Sbirth[50];char SQL[500];scanf("%d %s %s %s",&Sno,&Sname,&Ssex,&Sbirth);
// printf("----%d %s %s %s----\n",Sno,Sname,Ssex,Sbirth);snprintf(SQL, 500, "INSERT INTO Student VALUES(%d,'%s','%s','%s');"\,Sno,Sname,Ssex,Sbirth);
// printf("正在执行2:%s\n",SQL);/* Execute SQL statement */rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);if( rc != SQLITE_OK ){fprintf(stderr, "插入失败SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{fprintf(stdout, "记录创建成功 \n");}} printf("执行完毕,进入主菜单\n"); func=99;}if(func==3){int num=-1;while(num==-1){printf("请输入删除表Student中的记录次数:"); scanf("%d",&num);} int i;for(i=0;i<num;i++){printf("输入删除表Student中的记录的学号,仅支持学号删除,例002:\n"); // SELECT * FROM Student WHERE Sno=02;int Sno;char SQL[500];scanf("%d",&Sno);
// printf("----%d %s %s %s----\n",Sno);snprintf(SQL, 500, "DELETE FROM Student WHERE Sno=%d;",Sno);
// printf("正在执行2:%s\n",SQL);/* Execute SQL statement */rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);if( rc != SQLITE_OK ){ fprintf(stderr, "删除失败,SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{fprintf(stdout, "删除成功\n");}} printf("执行完毕,进入主菜单\n"); func=99;}if(func==4){int num=-1;while(num==-1){printf("请输入修改表Student中的记录条数(仅限数字):"); scanf("%d",&num);} int i;for(i=0;i<num;i++){printf("请按输入需要修改的记录学号,格式:修改的学号,例\"001\" \n"); int Sno;char Sname[10],Ssex[2],Sbirth[50];char SQL[500];scanf("%d",&Sno);
// printf("----%d %s %s %s----\n",Sno);snprintf(SQL, 500, "SELECT * FROM Student WHERE Sno=%d;",Sno);
// printf("正在执行2:%s\n",SQL);/* Execute SQL statement */rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);if( rc != SQLITE_OK ){ fprintf(stderr, "查询失败,SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{if(haveInfo){fprintf(stdout, "查询成功,信息如上↑\n");haveInfo=0;}else{fprintf(stdout, "查询成功,未查询到相关信息\n");}}printf("请按输入新的记录内容,格式:学号 姓名 性别 生日"\",例\"001 辛明子 男 2000-10-10\"\n"); // INSERT INTO Student VALUES(002,'的','男','2000-10-10');scanf("%d %s %s %s",&Sno,&Sname,&Ssex,&Sbirth);
// printf("----%d %s %s %s----\n",Sno,Sname,Ssex,Sbirth);snprintf(SQL, 500, "UPDATE Student SET Sno=%d, Sname='%s'"\", Ssex='%s', Sbirth='%s' WHERE Sno = %d;",Sno,Sname,Ssex,Sbirth,Sno);
// printf("正在执行2:%s\n",SQL);/* Execute SQL statement */rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);if( rc != SQLITE_OK ){fprintf(stderr, "修改失败SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{fprintf(stdout, "记录修改成功 \n");}} printf("执行完毕,进入主菜单\n"); func=99;}if(func==5){int num=-1;while(num==-1){printf("请输入查询表Course中的记录次数:"); scanf("%d",&num);} int i;for(i=0;i<num;i++){printf("输入查询表Course中的记录的课程号," \"仅支持课程号查询,例002:\n"); // SELECT * FROM Course WHERE Cno=02;int Cno;char SQL[500];scanf("%d",&Cno);
// printf("----%d %s %s %s----\n",Cno);snprintf(SQL, 500, "SELECT * FROM Course WHERE Cno=%d;",Cno);
// printf("正在执行2:%s\n",SQL);/* Execute SQL statement */rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);if( rc != SQLITE_OK ){ fprintf(stderr, "查询失败,SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{if(haveInfo){fprintf(stdout, "查询成功,信息如上↑\n");haveInfo=0;}else{fprintf(stdout, "查询成功,未查询到相关信息\n");}}} printf("执行完毕,进入主菜单\n"); func=99;}if(func==6){int num=-1;while(num==-1){printf("请输入查询某个学生选修某一门课程的选课信息次数:"); scanf("%d",&num);} int i;for(i=0;i<num;i++){printf("要查询的学号和课程号,例002 002:\n"); // SELECT * FROM Course WHERE Cno=02;int Sno,Cno;char SQL[500];scanf("%d %d",&Sno,&Cno);// printf("----%d %s %s %s----\n",Cno);snprintf(SQL, 500, "SELECT Sno,Cname,Grade FROM Course,SC WHERE Course.Cno=SC.Cno AND SC.Cno=%d AND SC.Sno=%d;",Cno,Sno);// printf("正在执行2:%s\n",SQL);/* Execute SQL statement */rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);if( rc != SQLITE_OK ){ fprintf(stderr, "查询失败,SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{if(haveInfo){fprintf(stdout, "查询成功,信息如上↑\n");haveInfo=0;int funcc=-1;while(funcc==-1){printf("是否对该生该课程的成绩进行修改,键入1代表修改,键入0代表不修改\n");scanf("%d",&funcc);}if(funcc==1){printf("请输入新的成绩\n");scanf("%d",&funcc);} snprintf(SQL, 500, "UPDATE SC SET Grade=%d WHERE Cno=%d AND Sno=%d;",funcc,Cno,Sno);// printf("正在执行2:%s\n",SQL);/* Execute SQL statement */rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);if( rc != SQLITE_OK ){ fprintf(stderr, "更新失败,SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}else{fprintf(stdout, "更新成功\n");}}else{fprintf(stdout, "查询成功,未查询到相关信息\n");}}}printf("执行完毕,进入主菜单\n"); func=99;}if(func==0){break;}}sqlite3_close(db);return 0;
}
以下截图代表交互式插入十条数据。
插入结束,查看数据库,信息插入成功。
以下截图交互式增加一条数据进入数据库中。
以下截图交互式删除一条数据进入数据库中。
以下截图交互式修改一条数据进入数据库中。
以下截图交互式查询一条数据于数据库中。
六、总结
以上就是今天要讲的内容,本文介绍了如何在Windows10系统下,安装SQLite,并使用DEV-CPP编译链接到SQLite,使用SQLite提供的C/C++的API进行嵌入式编程来操作数据库。
本文提供了简单的程序以嵌入式编程的方式来操作数据库,但仅涉及到增删改查,更为高级的数据库操作带读者进一步开发。
七、参考
SQLite官网:https://www.sqlite.org/index.html
菜鸟教程:https://www.runoob.com/sqlite/sqlite-tutorial.html
【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库相关推荐
- linux下C语言编程操作数据库(sqlite3)
前言:C语言中通过调用 sqlite 的函数接口来实现对数据库的管理(创建数据库.创建表格.插入数据.查询.数据.删除数据等),掌握sqlite数据库的语法,以及sqlite提供的函数接口,那么在li ...
- 嵌入式数据库-SQLite3的基本指令及用C语言操作数据库
SQLite简介: 轻量化,易用的嵌入式数据库,用于设备端的数据管理,可以理解成单点的数据库. 传统服务器型数据 库用于管理多端设备,更加复杂.SQLite是一个无服务器的数据库,是自包含的.这也称为 ...
- linux c编程操作数据库(sqlite3应用)
C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理(创建数据库.创建表格.插入数据.查询.数据.删除数据等). 首先要编译好 sqlite的库文件 : libsqlite3 ...
- linux c 数据库编程,linux c 编程操作数据库(sqlite3应用)
C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理(创建数据库.创建表格.插入数据.查询数据.删除数据等). 首先要编译好sqlite的库文件 : libsqlite3.a libsq ...
- 数据库学mysql python_mysql学习(4)python操作数据库
整理了一下前面3期学的内容后,现在练习使用python去操作数据库 #!python3 # coding:utf-8 import pymysql class mysql_option(): def ...
- php操作数据库的五个步骤,请写出PHP操作数据库的五个步骤
请写出PHP操作数据库的五个步骤 答: 连接数据库服务器 选择数据库 执行SQL语句 处理结果集 关闭资源,释放连接 上盘相对下降,下盘相对上升的断层是 答:正断层 绍兴文戏时期分为男班时期和女班时期 ...
- TP6中db操作数据库的方式(方法)和ORM模型操作数据库的方式(方法)
db库认知基础 注:orm独立出来了,与tp5不同 配置数据库: 通过env文件来具体配置,目的是不同的环境下,如线上服务器的配置只需要使用本环境的env文件就可以直接更改配置了 使用db: ① tp ...
- 数据库|SQLite数据库
SQLite数据库 数据库(Database)是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合.常用的数据分为大型.中型和小型数据库. 1. SQLite数据库 SQLite是一款轻型的嵌 ...
- android realm 简书,android 数据库SQLite realm
一.SQLite android内置了数据库SQLite,这是一款轻量级的关系型数据库,通常只需要几百K的内存.数据库文件存放在/data/data//databases/目录下. 为了方便管理数据库 ...
- SQLAlchemy 操作数据库
SQLAlchemy 操作数据库 SQLAlchemy为Python提供了不同数据库的统一接口,采用ORM的方式操作数据库,简洁优雅 一.安装 直接通过pip安装即可 pip install sqla ...
最新文章
- AI 重新定义金融,颠覆投资模式
- ASP.NET中MVC添加Controller以及访问其Action
- TCPDUMP/LIBPCAP 2-搭建环境
- 华师 计算机系统 作业,华师网络学院作业答案-计算机组成原理问答题
- 【WS-Federation】到底有多少公司在用WS-Federation
- 2.两数相加(leetcode-2)
- 基于树莓派的人脸识别门禁系统
- 常用计算机二级题库,2016最新计算机二级office题库
- 算法面试题:切割木头,给定一个数组nums,nums[i]表示每个木头的长度,木头可以截断,现在需要k根长度一样的木头,每根木头最大长度为多少
- TypeScript 学习笔记(十万字超详细知识点总结)
- 使用 C++ 开发出 【飞机大战】
- ping不通百度 ubuntu_Ubuntu不可以ping百度,但是可以ping通其ip
- Vue:首屏加载页实现
- 【知识图谱】实践篇——基于医疗知识图谱的问答系统实践(Part5-完结):信息检索与结果组装
- Halting Problem的讨论
- openpyxl 单元格合并
- Windows Server 2012 R2安装域控制器完整版
- oppor17刷鸿蒙系统,三个原因告诉你 为何OPPO R17能够如此受追捧
- 日语形容词变化规律总结
- ANDROID OTA FOTA
热门文章
- MySql 免费数据库管理工具
- numpy复习总结,为深度学习打下基础
- 初识STM32与其选型
- 单片机IC卡读取开题报告_基于单片机的IC卡读写器设计(含开题报告)
- 信号与线性系统管致中第六版pdf_2021年武汉工程大学834信号与系统考研全套
- 【无标题】手机扩容或更换字库后的指纹. 基带. 账号 .解锁等故障分析
- java线上编译器菜鸟_[Java教程]菜鸟成长记
- 高等代数——大学高等代数课程创新教材(丘维声)——第0章 笔记+习题
- matlab delay用法,请教Vensim中DELAY1I函数使用的单位设置
- 组态软件mcgs入库mysql_MCGS组态软件实现数据报表