lv9 嵌入式开发 数据库sqlite

news2024/11/25 3:09:31

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_OK

5--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  128

int 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_t

void 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斤....
超市每天水果都有进货和卖出嘛,水果的价格随着季节和天气也会有波动,顾客也会看一下每天水果的价格的嘛,
所以要求,根据上述提示,利用数据库完成水果店各种水果的增(进货)删(卖出)改(波动)查(看价格)功能。
并将进出货的时间和顾客光顾的时间记录到数据库中保存。

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

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

相关文章

竞赛 深度学习猫狗分类 - python opencv cnn

文章目录 0 前言1 课题背景2 使用CNN进行猫狗分类3 数据集处理4 神经网络的编写5 Tensorflow计算图的构建6 模型的训练和测试7 预测效果8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习猫狗分类 ** 该项目较为新颖&a…

google scholar 显示异常流量

有时候可能会出现下图警告&#xff0c;导致打不开谷歌学术的界面&#xff0c;我们需要修改一下访问网址 在网站后面添加 .pk 或者 .pr &#xff0c;如下&#xff1a; https://scholar.google.com.pk/https://scholar.google.com.pr/

网络变压器/网络滤波器/脉冲变压器接地电路的选择

Hqst华强盛(盈盛)电子导读&#xff1a;网络变压器/网络滤波器/脉冲变压器&#xff0c;以下都称网络变压器&#xff0c;它的接地在网络布置中非常重要&#xff0c;它可以有效地提高信号的稳定性和可靠性。 网络变压器接地的布置方式通常有以下几种&#xff1a; 一&#xff0c;单…

Rust学习日记(二)变量的使用--结合--温度换算/斐波那契数列--实例

前言&#xff1a; 这是一个系列的学习笔记&#xff0c;会将笔者学习Rust语言的心得记录。 当然&#xff0c;这并非是流水账似的记录&#xff0c;而是结合实际程序项目的记录&#xff0c;如果你也对Rust感兴趣&#xff0c;那么我们可以一起交流探讨&#xff0c;使用Rust来构建程…

《算法通关村—原来如此简单》

《算法通关村—原来如此简单》 理解层序遍历 我们有一个二叉树&#xff0c;我们如何去进行一层一层的遍历呢&#xff1f; 需要我们借用一个数据结构来进行遍历&#xff0c;数据结构就是队列。我们首先把根节点放入队列中&#xff0c;然后从此进行遍历。如何进行遍历&#xf…

SpringBoot项目从resources目录读取文件

SpringBoot 从 resources 读取文件 使用 Spring 给我们提供的工具类来进行读取 File file org.springframework.util.ResourceUtils.getFile("classpath:人物模板.docx");可能读取失败&#xff0c;出现如下错误&#xff1a; java.io.FileNotFoundException: clas…

JSP 中医知识管理系统myeclipse开发sql数据库BS模式java编程网页结构

一、源码特点 JSP 中医知识管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;比较流行的ssh框架系统具有完整的源代码和数据库&#xff0c;myeclipse开发系统主要采用B/S模式开发。 javaWeb中医知识系统 二、功能介绍 此次系统主要…

电脑提示由于找不到msvcp120.dll无法继续执行代码的问题如何解决

在打开软件过程中&#xff0c;我们可能会遇到各种错误和问题。其中之一就是msvcp120.dll无法继续执行代码的问题。这个问题通常是由于缺少或损坏的Microsoft Visual C Redistributable Packages导致的。为了解决这个问题&#xff0c;我们可以采取以下四个解决方案&#xff1a; …

【逗老师的无线电】BI1FQO教你整骚活,纯4G MMDVM热点版

开篇图&#xff0c;看我手搓出来的尺寸超小的MMDVM热点盒子&#xff08;都不能叫做盒子啦&#xff09; 咱就说这玩意尺寸有多小&#xff0c;架构有多简单&#xff0c;4G网卡直连双工热点版&#xff0c;省去树莓派或者OpenWrt&#xff0c;功耗低至0.几W。开机秒快。 基本原…

大数据管理平台是什么?如何利用工单系统提升企业管理效率?

随着数字化时代的来临&#xff0c;大数据管理平台已成为企业优化运营、提高竞争力的关键工具。工单管理系统作为大数据管理平台的核心组件&#xff0c;对于企业服务的优化和提升发挥着至关重要的作用。本文小编将为您揭示工单管理系统在大数据管理平台中的重要地位&#xff0c;…

libpcap之数据分流

当前系统都是多核系统&#xff0c;为了充分利用多核优势&#xff0c;数据包可以在底层就进行分流&#xff0c;可以通过多线程/多进程对同一个接口的数据进行并行的处理。 一、实验 一个server/client程序一个简单的抓包程序&#xff0c;抓取server/client之间的通信数据 1.1 …

Bat批量处理

一&#xff1a;创建文件夹 excel创建文件 复制出来新建文本文件 另存为bat 双击bat 二&#xff1a;批量移动文件 A列&#xff1a;获取的文件名列表 dir /b/o:n> original.txt B列&#xff1a;填充序号 C列公式&#xff1a;每隔9行增加1 INT((ROW(B1)-1)/9)1 D列公式&am…

CDN与WAF防火墙:强强联手,守护您的网站安全

随着互联网的普及&#xff0c;网站安全问题变得愈发重要。恶意攻击、数据泄露和服务中断等问题都可能给网站和用户带来严重损害。在保护网站免受这些威胁的过程中&#xff0c;内容分发网络&#xff08;CDN&#xff09;和Web应用程序防火墙&#xff08;WAF&#xff09;是两个强大…

C++算法 —— 贪心(2)

文章目录 1、柠檬水找零2、将数组和减半的最少操作次数3、最大数4、摆动序列5、最长递增子序列6、递增的三元子序列7、最长连续递增子序列 1、柠檬水找零 860. 柠檬水找零 如果一开始顾客给了10块&#xff0c;那就直接结束。给了5块那就收下。之后每一个位置&#xff0c;都需要…

进阶C语言-指针的进阶(三)

模拟实现qsort函数 &#x1f388;1.测试bubble_sort&#xff0c;排序整型数组&#x1f388;2测试bubble_sort&#xff0c;排序结构体数组 &#x1f4dd;关于qsort函数&#xff0c;我们可以先去cpluplus网站上面了解一下&#xff1a; //1.排序整型数组&#xff0c;两个整型可以…

Linux 上的轻量级浏览器

导读大多数 Linux 桌面环境中包含的基本图像查看器可能不足以满足你的需要。如果你想要一些更多的功能&#xff0c;但仍然希望它是轻量级的&#xff0c;那么看看这四个 Linux 桌面中的图像查看器&#xff0c;如果还不能满足你的需要&#xff0c;还有额外的选择。 当你需要的不…

竞赛选题 深度学习实现语义分割算法系统 - 机器视觉

文章目录 1 前言2 概念介绍2.1 什么是图像语义分割 3 条件随机场的深度学习模型3\. 1 多尺度特征融合 4 语义分割开发过程4.1 建立4.2 下载CamVid数据集4.3 加载CamVid图像4.4 加载CamVid像素标签图像 5 PyTorch 实现语义分割5.1 数据集准备5.2 训练基准模型5.3 损失函数5.4 归…

整理的一些Java细节问题

1. 为什么要有无参构造&#xff1f; 在 Java 中&#xff0c;如果一个类没有显式定义构造方法&#xff0c;编译器会自动生成一个默认的无参构造方法&#xff08;也称为默认构造方法&#xff09;。无参构造方法是一个没有任何参数的构造方法。 无参构造方法的存在有几个重要原因…

【vscode输出中文乱码】

vscode输出中文乱码为一个个的问号。 这个链接亲测有用 win11对应的界面在这里&#xff1a;

产品经理入门学习(二):产品经理问题思考维度

参考引用 黑马-产品经理入门基础课程 1. 抓住核心用户 1.1 为什么要抓住核心用户 什么是用户&#xff1f; 所有和产品有关系的群体就是用户&#xff0c;他们是一群既有共性&#xff0c;又有差异的群体组合 做产品为什么要了解用户&#xff1f; 了解用户的付费点、更好的优化产…