L7数据库开发-嵌入式数据库之sqlite3(D1、D2)

目录

一、数据库概念介绍

 一、数据库基本概念

二、常用数据库 

三、基于嵌入式的数据库 

二、SQLite基础

 一、数据库的安装

二、数据库基本命令

操作实例: 

命令: 

二、数据库之API操作

一、SQLite编程接口

代码举例:

student.c:

 如果要求定义一级指针,就取地址,二级指针就定义一级指针取地址,以此类推。

 代码:

 回调函数解析:

day1作业:

day2作业: 


一、数据库概念介绍

 一、数据库基本概念

1、数据:能够输入计算机并能被计算机程序识别和处理的信息集合

2、数据库: 数据库数据库管理系统管理和控制之下,存放在存储介质上数据集合

二、常用数据库 

1、大型数据库 :

Oracle 公司是最早开发关系数据库的厂商之一,其产品支持最广泛的操作系统平台。目前 Oracle 关系数据库产品的市场占有率名列前茅。
IBM DB2 是第一个具备网上功能的多媒体关系数据库管理系统 ,支持包 Linux 在内的一系列平台。

2、中型数据库: Server是微软开发的数据库产品,主要支持windows平台。

3、小型数据库: mySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,2008年被Sun公司收购,开放源码。

三、基于嵌入式的数据库 

基于嵌入式Linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB
2、Firebird 是关系型数据库 , 功能强大 , 支持存储过程、 SQL 兼容等
3、SQLite 关系型数据库 , 体积小 , 支持 ACID 事务
4、Berkeley DB 中并没有数据库服务器的概念,它的程序库直接链接到应用程序中
5、eXtremeDB 是内存数据库 , 运行效率

二、SQLite基础

SQLite 的源代码是 C ,其源代码完全开放。 SQLite 第一个 Alpha 版本诞生于 2000 5 月。 他是一个轻量级的嵌入式数据库。
SQLite 有以下特性:
配置一无需安装和管理配置;
储存 在单一磁盘文件中的一个完整的数据库;
数据库 文件可以在不同字节顺序的机器间自由共享;
支持 数据库大小至 2TB
足够 小,全部源码大致 3 万行 c 代码, 250KB
目前流行的大多数数据库对数据的操作要快

 一、数据库的安装

1、本地安装:(先下载) sudo dpkg -i  *.deb

2、在线安装:sudo apt-get install sqlite3

二、数据库基本命令

      1)系统命令 , 都以'.'开头
         .exit 
         .quit
         .table   查看表
         .schema  查看表的结构
          
      2)sql语句, 都以‘;’结尾

        1-- 创建一张表
            create table stuinfo表名(id integer, name text, age integer, score float);
        
        2-- 插入一条记录(缺点:sqlite对数据类型不严格检测,错了也能插进去)
            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;  //id为1003的年龄改为20
            update stuinfo set age=30, score = 82 where id=1003;

        6-- 删除一张表
            drop table stuinfo;

        7-- 增加一列
            alter table stuinfo add column sex char;

        8-- 删除一列(不支持直接删除一列)
            create table stu as select id, name, score from stuinfo;   //创建一个新的表
            drop table stuinfo;                                           //删除原有的表
            alter table stu rename to stuinfo;   // 将新表的名字改为旧表的名字

     数据库设置主键:
     create table info(id integer primary key autoincrement, name vchar);

操作实例: 

 

 

命令: 

二、数据库之API操作

一、SQLite编程接口

int    sqlite3_open(char  *path,   sqlite3 ** db )
功能 :打开 sqlite 数据库
path :数据库 文件 路径
db :指向 sqlite 句柄的 指针(二级指针)
返回 值:成功返回 0 ,失败返回错误码 ( 非零值 )
int    sqlite3_close(sqlite3 * db );
功能 :关闭 sqlite 数据库        
返回 值:成功返回 0 ,失败返回 错误码
const   char  *sqlite3_errmg(sqlite3 * db );        
功能 :通过db句柄,得到数据库操作的错误信息
返回 值:返回 错误信息

 

typedef  int (*sqlite3_callback)(void *, int , char **, char **);
int sqlite3_exec(sqlite3 * db , const   char  * sql , sqlite3_callback callback, void * arg, char  ** errmsg );
功能 :执行 SQL 操作
db :数据库 句柄
sql SQL 语句
callback :回调函数,只有sql为查询语句时,才会执行此语句。
errmsg :错误信息指针的地址
―arg :为回调函数传递参数
返回 值:成功返回 0 ,失败返回 错误码

代码举例:

student.c:

#include<stdio.h>
#include<sqlite3.h>
#include<stdlib.h>
#include<string.h>

#define DATABASE "stu.db"//定义数据库名

int do_insert(sqlite3 *db)
{
	int id;
	char name[32] = {};
	int score;
	char sql[128] = {};
	char *errmsg;

	printf("Input id:");
	scanf("%d",&id);
	getchar();

	printf("Input name:");
	scanf("%s",name);
	getchar();

	printf("Input score:");
	scanf("%d",&score);
	getchar();

	sprintf(sql,"insert into stu values(%d,'%s',%d);",id,name,score);//塑造sql命令

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);

	}
	else
	{
		printf("Insert done.\n");
	}

	return 0;
}

int main(int argc, const char *argv[])
{
	sqlite3 * db;
	char *errmsg;
	int cmd;

	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 stu (id Integer ,name char, score Tnteger);", NULL, NULL,&errmsg) != SQLITE_OK)//不等于说明失败
	{
		printf("%s\n",errmsg);//打印错误信息
	
	}
	else
	{
		printf("create table or open success.\n");
	}

	while(1)
	{
		printf("************************************\n");
		printf("1:insert 2:delete 3:query 4:update 5:quit.\n");
		printf("************************************\n");

		scanf("%d", &cmd);
		getchar();//吃掉scanf的空格
				  //
		switch(cmd)
		{
		case 1:
			do_insert(db);
			break;
		case 2:
			//do_delete();
			break;
		case 3:
			//do_query();
			break;
		case 4:
			//do_update();
			break;
		case 5:
			//sqlite3_close(db);
			exit(0);
		defalut:
			printf("Error cmd.\n");
		}
	return 0;
}//括号应放在return 0 前。
}

运行结果:

 
查询回调函数:

typedef  int (*sqlite3_callback)(void *para, int f_num , char ** f_value , char ** f_name );
功能 :每找到一条记录自动执行一次回调函数
para :传递给回调函数的参数
f_num :记录中包含的字段(列)数目
f_value :包含每个字段值的指针 数组
f_name :包含每个字段名称的指针 数组
返回 值:成功返回 0 ,失败返回 - 1

           

不使用回调函数执行 SQL 语句
int    sqlite3_get_table(sqlite3 * db , const   char  * sql ,  char *** resultp int * nrow int * ncolumn , char ** errmsg );
功能 :执行 SQL 操作
db :数据库句柄
sql SQL 语句
resultp :用来指向 sql 执行结果的指针
nrow :满足条件的记录的 数目
ncolumn :每条记录包含的字段数目
errmsg :错误信息指针的地址
返回 值:成功返回 0 ,失败返回 错误码

 如果要求定义一级指针,就取地址,二级指针就定义一级指针取地址,以此类推。

 代码:

student.c:

#include<stdio.h>
#include<sqlite3.h>
#include<stdlib.h>
#include<string.h>

#define DATABASE "stu.db"//定义数据库名
#define  N  128

int do_insert(sqlite3 *db)
{
	int id;
	char name[32] = {};
	char sex;
	int score;
	char sql[128] = {};
	char *errmsg;

	printf("Input id:");
	scanf("%d",&id);
	getchar();

	printf("Input name:");
	scanf("%s",name);
	getchar();

	printf("Input score:");
	scanf("%d",&score);
	getchar();

	sprintf(sql,"insert into stu values(%d,'%s',%d);",id,name,score);//塑造sql命令

	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:");//根据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 *errmsg;
	int score;

	printf("Input update id:");
	scanf("%d", &id);
	getchar();

	printf("Update score:");
	scanf("%d",&score);
	getchar();

	sprintf(sql, "update stu set score=%d where id=%d", score,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("%-11s", f_value[i]);
	}

	printf("++++++++++++++++++++++");
	putchar(10);//代表换行(输出时系统会将10转换为字符,在ASCLL表中,第10个是换行符,故会输出换行符)

	return 0;
}


//查询
int do_query(sqlite3 *db)
{
	char *errmsg;
	char sql[N] = "select * from stu;";

	if(sqlite3_exec(db, sql, callback,NULL , &errmsg) != SQLITE_OK)
	{
		printf("%s\n", errmsg);
	}
	else
	{
		printf("query 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("%-11s ", resultp[j]);
	}
	putchar(10);

	for(i = 0; i < nrow; i++)
	{
		for(j = 0; j < ncolumn; j++)
		{
			printf("%-11s ", resultp[index++]);
		}
		putchar(10);
	}

return 0;
}

int main(int argc, const char *argv[])
{
	sqlite3 * db;
	char *errmsg;
	int cmd;

	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 stu (id Integer ,name char, score Tnteger);", NULL, NULL,&errmsg) != SQLITE_OK)//不等于说明失败
	{
		printf("%s\n",errmsg);//打印错误信息
	
	}
	else
	{
		printf("create table or open success.\n");
	}

	while(1)
	{
		printf("************************************\n");
		printf("1:insert 2:delete 3:query 4:update 5:quit.\n");
		printf("************************************\n");
		
		printf("Input cmd:");
		scanf("%d", &cmd);
		getchar();//吃掉scanf的空格
				  //
		switch(cmd)
		{
		case 1:
			do_insert(db);
			break;
		case 2:
			do_delete(db);
			break;
		case 3:
			//do_query(db);
			do_query1(db);
			break;
		case 4:
			do_update(db);
			break;
		case 5:
			sqlite3_close(db);
			exit(0);
		defalut:
			printf("Error cmd.\n");
		}
		}
	return 0;

}

 运行结果:

 回调函数解析:

  • 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。——知乎

day1作业:

1.如何将某一字段设置为自增字段 ,如何为自增字段赋值?(自己作为扩展的内容去学习)
2.重点理解回调函数的使用,可以参考signal函数,然后自己写一个回到函数和函数指针的测试代码测试一下函数的使用并提交代码
(注:内核中到处都是函数指针和回调函数,参考示例的链接:https://www.cnblogs.com/jontian/p/5619641.html )
(作业要求:做作业的时候不要再翻看视频上的教程,对函数理解不明白的全部通过man手册去查看,
自己思考框架,使用makefile编译,然后将测试的记录和结果添加到readme.txt文件中提交上来,代码实现完成测试通过后
再提交作业,网络部分学习不写代码不测试看不出问题的,良好的习惯帮助你们快速成长。)

 sqlite创建自增字段浅谈(AUTOINCREMENT)_Commas.KM的博客-CSDN博客_sqlite 自增字段

回调函数(callback)浅析、理解及代码分析。_禾仔仔的博客-CSDN博客 

day2作业: 

假如我家开了个水果超市,有以下水果,想实现自动化管理,扫描二维码就能知道当前的水果状态,进货几天了,
好久需要再次进货,那些水果畅销,那些水果不畅销,那些水果春夏秋冬的价格波动,好,那么现在我想将
这些信息保存在数据库中,那么我应该怎么做;
提示: 建立一张fruit表,
假如水果有: 苹果,香蕉,梨,橘子,葡萄....(可以自己查一下英文保存到数据库)
水果价格: 苹果 5元/斤 香蕉 3元/斤 梨 3.5元/斤 橘子2.5元/斤 葡萄 8元/斤....
当前存货: 苹果 80斤 香蕉 200斤 梨 50斤 橘子300斤 葡萄 100斤....
超市每天水果都有进货和卖出嘛,水果的价格随着季节和天气也会有波动,顾客也会看一下每天水果的价格的嘛,
所以要求,根据上述提示,利用数据库完成水果店各种水果的增(进货)删(卖出)改(波动)查(看价格)功能。
并将进出货的时间和顾客光顾的时间记录到数据库中保存。

(作业要求:做作业的时候不要再翻看视频上的教程,对函数理解不明白的全部通过man手册去查看,
自己思考框架,使用makefile编译,然后将测试的记录和结果添加到readme.txt文件中提交上来,代码实现完成测试通过后
再提交作业,这部分学习不写代码不测试看不出问题的,良好的习惯帮助你们快速成长。)

 fruit.c:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
 
 
int do_insert(sqlite3 * db)
{
	char catagory[32]={0};
	float price;
	int inventory;
	char incometime[32]={0};
	char * errmsg;
	char sql[1024] = {0};
	printf("plz input catagory:");
	scanf("%s",catagory);
	getchar();
 
	printf("plz input price:");
	scanf("%f",&price);
	getchar();
	
	printf("plz input inventory:");
	scanf("%d",&inventory);
	getchar();
 
	printf("plz input incometime:");
	scanf("%s",incometime);
	getchar();
 
	sprintf(sql,"insert into fruit(catagory,price,inventory,incometime) values('%s',%f,%d,'%s');",catagory,price,inventory,incometime);
	printf("%s",sql);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		if(strstr(errmsg,"UNIQUE") == NULL)
		{
			printf("%s\n",errmsg);
			return -1;
		}
		sprintf(sql,"update fruit set price = %f, inventory = %d, incometime = '%s' where catagory = '%s';",price,inventory,incometime,catagory);
		if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
		{
			printf("%s\n",errmsg);
			return -1;
		}
	}
	printf("insert successfully\n");
	return 0;
}
 
 
int do_delete(sqlite3 * db)
{
	char catagory[32] = {0};
	int inventory;
	char saletime[32]  = {0};
	char * errmsg;
	char sql[1024] = {0};
	printf("plz input catagory:");
	scanf("%s",catagory);
	getchar();
 
	printf("plz input inventory:");
	scanf("%d",&inventory);
	getchar();
	
	printf("plz input saletime:");
	scanf("%s",saletime);
 
	sprintf(sql,"update fruit set inventory = %d,saletime = '%s' where catagory = '%s';",inventory,saletime,catagory);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
		return -1;
	}
	return 0;
}
 
int do_update(sqlite3 * db)
{
	char catagory[32] = {0};
	float price;
	char * errmsg;
	char sql[1024] = {0};
	printf("plz input catagory:");
	scanf("%s",catagory);
	getchar();
 
	printf("plz input price:");
	scanf("%f",&price);
	getchar();
	
	sprintf(sql,"update fruit set price = %f where catagory = '%s';",price,catagory);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
		return -1;
	}
	return 0;
}
 
int callback(void * arg,int f_num,char ** f_value,char ** f_name)
{
	printf("price:%s\n",f_value[1]);
	return 0;
}
 
int do_query(sqlite3 * db)
{
	char catagory[32] = {0};
	float price;
	char * errmsg;
	char sql[1024] = {0};
	printf("plz input catagory:");
	scanf("%s",catagory);
	getchar();
	
	sprintf(sql,"select * from fruit where catagory = '%s';",catagory);
	if(sqlite3_exec(db,sql,callback,NULL,&errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
		return -1;
	}
	return 0;
}
int main()
{
	sqlite3 * db;
	char * errmsg;
	//打开数据库
	if(sqlite3_open("./fruit.db",&db) != SQLITE_OK)
	{
		printf("%s\n",sqlite3_errmsg(db));
		exit(-1);
	}
	//新建表
	if(sqlite3_exec(db,"create table fruit (catagory char unique, price float, inventory Interger, incometime char,saletime char);",NULL,NULL,&errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
		exit(-1);
	}
	int cmd;
	while(1)
	{
		printf("1:insert 2:delete 3:update 4:query 5:quit\n");
		printf("plz input the number\n");
		scanf("%d",&cmd);
		getchar();
		switch(cmd)
		{
			case 1:
				do_insert(db);
				break;
			case 2:
				do_delete(db);
				break;
			case 3:
				do_update(db);
				break;
			case 4:
				do_query(db);
				break;
			case 5:
				sqlite3_close(db);
				exit(0);
			default:
				printf("cmd error\n");
 
		}
	}
	return 0;
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值