lv9 嵌入式开发 数据库sqlite
1 数据库基本概念
数据(Data)
能够输入计算机并能被计算机程序识别和处理的信息集合
数据库 (Database)
数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合
2 常用的数据库
大型数据库
Oracle公司是最早开发关系数据库的厂商之一,其产品支持最广泛的操作系统平台。目前Oracle关系数据库产品的市场占有率名列前茅。
IBM 的DB2是第一个具备网上功能的多媒体关系数据库管理系统,支持包Linux在内的一系列平台。
中型数据库
Server是微软开发的数据库产品,主要支持windows平台。
小型数据库
mySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,2008年被Sun公司收购,开放源码。
3 基于嵌入式的数据库
- 基于嵌入式Linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB
- Firebird是关系型数据库,功能强大,支持存储过程、SQL兼容等
- SQLite关系型数据库,体积小,支持ACID事务
- Berkeley DB中并没有数据库服务器的概念,它的程序库直接链接到应用程序中
- eXtremeDB是内存数据库,运行效率高
4 SQLite 基础
SQLite的源代码是C,其源代码完全开放。SQLite第一个Alpha版本诞生于2000年5月。 他是一个轻量级的嵌入式数据库。
SQLite有以下特性:
- 零配置一无需安装和管理配置;
- 储存在单一磁盘文件中的一个完整的数据库;
- 数据库文件可以在不同字节顺序的机器间自由共享;
- 支持数据库大小至2TB;
- 足够小,全部源码大致3万行c代码,250KB;
- 比目前流行的大多数数据库对数据的操作要快;
4.1 创建数据库方式介绍
手工创建
使用SQLite3工具,通过手工输入SQL命令行完成数据库创建. 用户在Linux的命令行界面中输入SQLite3可启动SQLite3工具
代码创建
在代码中常动态创建数据库 在程序运行过程中,当需要进行数据库操作时,应用程序会首先尝试打开数据库,此时如果数据库并不存在,程序则会自动建立数据库,然后再打开数据库
4.2 安装数据库
本地安装
sudo dpkg -i *.deb
在线安装
sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev
在终端下运行,出现如下提示符,说明数据库安装成功,<*.db> 是要打开的数据库文件。若该文件不存在,则自动创建
sqlite3 <*.db>SQLite version 3.7.2
Enter “.help” for instructions
Enter SQL statements terminated with a “;”
sqlite>
4.3 数据库系统命令
系统命令 , 都以'.'开头
显示所有命令
sqlite>.help
退出sqlite3
sqlite>.quit
显示当前打开的数据库文件
sqlite>.database
显示数据库中所有表名
sqlite>.tables
查看表的结构
sqlite>.schema <table_name>
/*******************************************/
4.4 数据库SQL命令
sql语句, 都以‘;’结尾
1-- 创建一张表
create table stuinfo(id integer, name text, age integer, score float);2-- 插入一条记录
insert into stuinfo values(1001, 'zhangsan', 18, 80);
insert into stuinfo (id, name, score) values(1002, 'lisi', 90);//插入部分字段3-- 查看数据库记录
select * from stuinfo; //查询
select * from stuinfo where score = 80;
select * from stuinfo where score = 80 and name= 'zhangsan';
select * from stuinfo where score = 80 or name='wangwu';
select name,score from stuinfo; 查询指定的字段
select * from stuinfo where score >= 85 and score < 90;4-- 删除一条记录
delete from stuinfo where id=1003 and name='zhangsan';5-- 更新一条记录
update stuinfo set age=20 where id=1003;
update stuinfo set age=30, score = 82 where id=1003;6-- 删除一张表
drop table stuinfo;7-- 增加一列
alter table stuinfo add column sex char;8-- 删除一列 //sqlite3不支持,直接删除一列
create table stu as select id, name, score from stuinfo; //第一步,创建新表
drop table stuinfo; //第二步,删除旧表
alter table stu rename to stuinfo; //第三步,改名9-- 数据库设置主键:
create table info(id integer primary key autoincrement, name vchar);
4.5 SQLite编程接口
具体文档参考sqlite-doc-3071700.rar,编程接口文档

1--打开数据库
int sqlite3_open(const char *filename, /* Database filename (UTF-8) */sqlite3 **ppDb /* OUT: SQLite db handle */
);
功能:打开数据库,如没有就创建一个
参数:filename 数据库名称ppdb 数据库句柄
返回值:成功为0 SQLITE_OK ,出错 错误码2--关闭数据库
int sqlite3_close(sqlite3* db);
功能:关闭数据库
参数:指针db
返回值:成功为0 SQLITE_OK ,出错 错误码3--获取错误信息描述
const char *sqlite3_errmsg(sqlite3*db);
功能:通过db句柄,得到数据库操作的错误信息的描述
参数:db
返回值:错误信息的首地址4--执行一条sql语句
int sqlite3_exec(sqlite3* db, /* An open database */const char *sql, /* SQL to be evaluated */int (*callback)(void* arg,int,char**,char**), /* Callback function */void * arg, /* 1st argument to callback */char **errmsg /* Error msg written here */
);
功能:执行一条sql语句
参数:db 数据库句柄sql sql语句callback 回调函数,只有在查询时,才传参执行此语句arg 为回调函数传递参数errmsg 错误消息
返回值:成功 SQLITE_OK5--sql执行回调函数
查询回调函数:
int (*callback)(void* arg,int ncolumns ,char** f_value,char** f_name), /* Callback function */
功能:查询语句执行之后,会回调此函数
参数:arg 接收sqlite3_exec 传递来的参数ncolumns 列数f_value 列的值得地址f_name 列的名称
返回值:0,6--不使用回调方式的执行sql语句
int sqlite3_get_table(sqlite3 *db, /* An open database */const char *zSql, /* SQL to be evaluated */char ***pazResult, /* Results of the query */int *pnRow, /* Number of result rows written here */int *pnColumn, /* Number of result columns written here */char **pzErrmsg /* Error msg written here */
);
功能:执行SQL操作
参数:db 数据库句柄sql SQL语句resultp 用来指向sql执行结果的指针nrow 满足条件的记录的数目ncolumn 每条记录包含的字段数目errmsg 错误信息指针的地址
返回值:成功返回0,失败返回错误码void sqlite3_free_table(char **result);
查询
示例:
注意查询可以使用回调机制,也可以不适用回调机制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>#define DATABASE "student.db"
#define N 128int do_insert(sqlite3 *db)
{int id;char name[32] = {};char sex;int score;char sql[N] = {};char *errmsg;printf("Input id:");scanf("%d", &id);printf("Input name:");scanf("%s", name);getchar();printf("Input sex:");scanf("%c", &sex);printf("Input score:");scanf("%d", &score);sprintf(sql, "insert into stu values(%d, '%s', '%c', %d)", id, name, sex, score);if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%s\n", errmsg);}else{printf("Insert done.\n");}return 0;
}
int do_delete(sqlite3 *db)
{int id;char sql[N] = {};char *errmsg;printf("Input id:");scanf("%d", &id);sprintf(sql, "delete from stu where id = %d", id);if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%s\n", errmsg);}else{printf("Delete done.\n");}return 0;
}
int do_update(sqlite3 *db)
{int id;char sql[N] = {};char name[32] = "zhangsan";char *errmsg;printf("Input id:");scanf("%d", &id);sprintf(sql, "update stu set name='%s' where id=%d", name,id);if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%s\n", errmsg);}else{printf("update done.\n");}return 0;
}int callback(void *arg, int f_num, char ** f_value, char ** f_name)
{int i = 0;for(i = 0; i < f_num; i++){// printf("%-8s %s", f_value[i], f_name[i]);printf("%-8s", f_value[i]);}printf("++++++++++++++++++++++");putchar(10);return 0;
}int do_query(sqlite3 *db)
{char *errmsg;char sql[N] = "select count(*) from stu where name='zhangsan';";if(sqlite3_exec(db, sql, callback,NULL , &errmsg) != SQLITE_OK){printf("%s", errmsg);}else{printf("select done.\n");}
}int do_query1(sqlite3 *db)
{char *errmsg;char ** resultp;int nrow;int ncolumn;if(sqlite3_get_table(db, "select * from stu", &resultp, &nrow, &ncolumn, &errmsg) != SQLITE_OK){printf("%s\n", errmsg);return -1;}else{printf("query done.\n");}int i = 0;int j = 0;int index = ncolumn;for(j = 0; j < ncolumn; j++){printf("%-10s ", resultp[j]);}putchar(10);for(i = 0; i < nrow; i++){for(j = 0; j < ncolumn; j++){printf("%-10s ", resultp[index++]);}putchar(10);}return 0;
}int main(int argc, const char *argv[])
{sqlite3 *db;char *errmsg;int n;if(sqlite3_open(DATABASE, &db) != SQLITE_OK){printf("%s\n", sqlite3_errmsg(db));return -1;}else{printf("open DATABASE success.\n");}if(sqlite3_exec(db, "create table if not exists stu(id int, name char , sex char , score int);",NULL, NULL, &errmsg) != SQLITE_OK){printf("%s\n", errmsg);}else{printf("Create or open table success.\n");}while(1){printf("********************************************\n");printf("1: insert 2:query 3:delete 4:update 5:quit\n");printf("********************************************\n");printf("Please select:");scanf("%d", &n);switch(n){case 1:do_insert(db);break;case 2:do_query(db);// do_query1(db);break;case 3:do_delete(db);break;case 4:do_update(db);break;case 5:printf("main exit.\n");sqlite3_close(db);exit(0);break;default :printf("Invalid data n.\n");}}return 0;
}
编译需要添加链接
gcc student.c -lsqlite3
5 练习
1.如何将某一字段设置为自增字段 ,如何为自增字段赋值?
数据库设置主键,autoincrement修饰主键可以实现字段自增
create table info(id integer primary key autoincrement, name vchar);
2.理解回调函数的使用,自己写一个回到函数和函数指针的测试代码测试一下函数的使用
#include <stdio.h>typedef void (* func_t)(int); //使用typedef 定义函数指针类型func_tvoid handle(int cmd, func_t callback) //处理函数种调用回调函数
{printf("handle\n"); callback(cmd);
}void f1(int cmd) //函数1
{printf("f1:%d\n",cmd);
}void f2(int cmd) //函数2
{printf("f2:%d\n",cmd);
}int main(int argc, const char *argv[])
{handle(1,f1);handle(2,f2);return 0;
}//测试结果
linux@linux:~/Desktop/sqlite$ ./sqltest
handle
f1:1
handle
f2:2
3 假如我家开了个水果超市,有以下水果,想实现自动化管理,扫描二维码就能知道当前的水果状态,进货几天了,
好久需要再次进货,那些水果畅销,那些水果不畅销,那些水果春夏秋冬的价格波动,好,那么现在我想将
这些信息保存在数据库中,那么我应该怎么做;
提示: 建立一张fruit表,
假如水果有: 苹果,香蕉,梨,橘子,葡萄....(可以自己查一下英文保存到数据库)
水果价格: 苹果 5元/斤 香蕉 3元/斤 梨 3.5元/斤 橘子2.5元/斤 葡萄 8元/斤....
当前存货: 苹果 80斤 香蕉 200斤 梨 50斤 橘子300斤 葡萄 100斤....
超市每天水果都有进货和卖出嘛,水果的价格随着季节和天气也会有波动,顾客也会看一下每天水果的价格的嘛,
所以要求,根据上述提示,利用数据库完成水果店各种水果的增(进货)删(卖出)改(波动)查(看价格)功能。
并将进出货的时间和顾客光顾的时间记录到数据库中保存。
相关文章:
lv9 嵌入式开发 数据库sqlite
1 数据库基本概念 数据(Data) 能够输入计算机并能被计算机程序识别和处理的信息集合 数据库 (Database) 数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合 2 常用的数据库 大型数据库…...
「Verilog学习笔记」异步复位的串联T触发器
专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 分析 这道题目里我们有两个需要明确的点: 1. 什么是异步复位 2. 什么是串联的T触发器 关于第一个点,可以看我的这篇文章,已经整理好了&a…...
什么是51单片机,,如何写代码,并且烧录?
文章目录 1.单片机介绍2.Keil 5操作1.打开Keil 5 3 新建工程3.添加文件并写代码4.添加到group5,设置6.check7.编译8.打开头文件9 调整编辑器 4.烧录1.烧录程序2.串口查询 5.Debug1.首先编译2.调试3.查询 6 51单片机汇编指令1.格式2.符号3.寻址4.数据传送与交换指令5.交换指令6 …...
Multer 实现文件上传功能
Multer 实现文件上传功能 前言:Multer 安装和使用1、安装2、使用2-1 前端代码2-2 后端代码3、实现效果前言: post请求一般有4种数据类型: application/x-www-form-urlencodedmultipart/form-dataapplication/jsontext/xml相应后端Express会使用不同的中间件来解析不同类型的…...
Excel·VBA工作表导出为图片
《Excel转图片别再截图啦!用这4个方法,高清且无损!》,excel转为图片一般方法较为简单,那么能否使用vba将excel转为图片 选中区域导出为图片 zoom设置为2,导出图片较为清晰 Sub 选中区域导出为图片()Dim …...
【零基础抓包】Fiddler超详细教学(一)
Fiddler 1、什么是 Fiddler? Fiddler 是一个 HTTP 协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的 HTTP 通讯。Fiddler 提供了电脑端、移动端的抓包、包括 http 协议和 https 协议都可以捕获到报文并进行分析;可以设置断点调试、截取…...
快速入手maven
文章目录 Maven介绍Maven安装和配置基于IDEA的Maven工程创建梳理Maven工程GAVP属性Idea构建Maven JavaSE工程Idea构建Maven JavaEE工程1. 手动创建2. 插件方式创建 Maven工程项目结构说明Maven核心功能依赖和构建管理依赖传递和冲突依赖导入失败场景和解决方案扩展构建管理和插…...
Mysql Binlog日志
Mysql Binlog是二进制格式的日志文件,但是不能把binlog文件等同于OS系统某目录下的具体文件,这是狭隘的。Binlog是用来记录Mysql内部对数据库的改动(只记录对数据的修改操作),主要用于数据库的主从复制、数据同步以及增…...
高级深入--day45
官方站点:GitHub - rmax/scrapy-redis: Redis-based components for Scrapy. scrapy-redis的官方文档写的比较简洁,没有提及其运行原理,所以如果想全面的理解分布式爬虫的运行原理,还是得看scrapy-redis的源代码才行。 scrapy-r…...
shell_66.Linux修改或移除信号捕获
修改或移除信号捕获 要想在脚本中的不同位置进行不同的信号捕获处理,只需重新使用带有新选项的 trap 命令即可: $ cat trapmod.sh #!/bin/bash #Modifying a set trap # trap "echo Sorry...Ctrl-C is trapped." SIGINT # count1 whi…...
5 ip的分配
如上一节所述,需要和其他设备通信,那么需要先配置ip. 1、如何配置ip 1.可以使用 ifconfig,也可以使用 ip addr 2.设置好了以后,用这两个命令,将网卡 up 一下,就可以了 //---------------------------- 使…...
【Python机器学习】零基础掌握StackingClassifier集成学习
如何精确地预测花的种类?一个简单但强大的方法引入了! 在现实生活中,生物学家和园艺爱好者经常面临一个问题:如何准确地识别和分类不同种类的花?这不仅仅是一个纯粹的学术问题,也有实际应用,比如在植物育种、生态研究等方面。为 了解决这个问题,一种叫做堆叠分类(St…...
Spring Boot 常见面试题
目录 1.Spring Boot 快速入门什么是 Spring Boot?有什么优点?Spring Boot 与 Spring MVC 有什么区别?Spring 与 Spring Boot 有什么关系?✨什么是 Spring Boot Starters?Spring Boot 支持哪些内嵌 Servlet 容器?如何设…...
利用大语言模型(LLM )提高工作效率
日常工作就是面向 google/ 百度编程,除了给变量命名是手动输入,大多时候就是通过搜索引擎拷贝别人的代码,或者找到旧项目一段代码拷贝过来使用。这无疑是开发人员的真实写照;然而,通过搜索引擎搜索答案,无疑…...
[Linux打怪升级之路]-信号的产生
前言 作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、信号基础…...
Python教程---Python基础语法
1.程序中的几个基本概念 (1).表达式 表达式就是一个类似于数学公式的东西 比如:10 + 5 8 - 4 表达式一般仅仅用了计算一些结果,不会对程序产生实质性的影响 如果在交互模式中输入一个表达式,解释器会自动将表达式的结果输出 (2).语句 在程序中语句一般需要完成某种功能,…...
echarts 画散点图, x周,y周在指定位置标志一下
文章目录 echarts 画散点图, x周,y周在指定位置标志一下示例一例子二示例三 echarts 画散点图, x周,y周在指定位置标志一下 示例一 let scatterData {data: [[[-0.2, -0.6],[0.4, 0.3],[0.1, 0.4],[0.3, 0.5],[0.09, 0.1],[0.7,…...
Unity地面交互效果——3、曲面细分基础知识
大家好,我是阿赵。 之前介绍了使用动态法线贴图混合的方式模拟轨迹的凹凸感,这次来讲一下更真实的凹凸感制作。不过在说这个内容之前,这一篇先要介绍一下曲面细分着色器(Tessellation Shader)的用法。 一、为什么要做曲面细分 之前通过法…...
NOIP 赛前模拟总结(第一周)
10.24 虽然今天我过了一道题,成为了少数过了题的人,但是排名没有想象中那么高,充分说明了打暴力的重要性,有时候你拼正解可能还没有你打满暴力考得好。 一定要打满暴力!一定要打满暴力!一定要打满暴力&am…...
stm32 DMA
目录 简介 框图 DMA请求 DMA通道 DMA优先级 DMA 数据 外设到存储器 存储器到外设 存储器到存储器 传多少,单位是什么 传输完成 hal库代码 标准库代码 简介 CPU根据代码内容执行指令,这些众多指令中,有的用于计算、有的用于控制程…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
