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

在线安装

cpp 复制代码
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语句, 都以';'结尾

cpp 复制代码
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,编程接口文档

cpp 复制代码
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);
查询

示例:

注意查询可以使用回调机制,也可以不适用回调机制

cpp 复制代码
#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;
}

编译需要添加链接

cpp 复制代码
gcc student.c -lsqlite3

5 练习

1.如何将某一字段设置为自增字段 ,如何为自增字段赋值?

数据库设置主键,autoincrement修饰主键可以实现字段自增

create table info(id integer primary key autoincrement, name vchar);

2.理解回调函数的使用,自己写一个回到函数和函数指针的测试代码测试一下函数的使用

cpp 复制代码
#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斤....

超市每天水果都有进货和卖出嘛,水果的价格随着季节和天气也会有波动,顾客也会看一下每天水果的价格的嘛,

所以要求,根据上述提示,利用数据库完成水果店各种水果的增(进货)删(卖出)改(波动)查(看价格)功能。

并将进出货的时间和顾客光顾的时间记录到数据库中保存。

相关推荐
野槐14 分钟前
node.js连接mysql写接口(一)
数据库·mysql
Zzzone68343 分钟前
PostgreSQL日常维护
数据库·postgresql
chxii44 分钟前
1.13使用 Node.js 操作 SQLite
数据库·sqlite·node.js
冰刀画的圈1 小时前
修改Oracle编码
数据库·oracle
这个胖子不太裤1 小时前
Django(自用)
数据库·django·sqlite
麻辣清汤1 小时前
MySQL 索引类型及其必要性与优点
数据库·mysql
腾飞的信仰2 小时前
单片机,主循环和中断资源访问冲突的案例
单片机·嵌入式硬件
2501_915374352 小时前
Neo4j 图数据库安装教程(2024最新版)—— Windows / Linux / macOS 全平台指南
数据库·windows·neo4j
it-搬运工3 小时前
3.图数据Neo4j - CQL的使用
数据库·neo4j
-借我杀死庸碌的情怀-3 小时前
navicat可视化页面直接修改数据库密码——mysql、postgresql、mangodb等
数据库·mysql·postgresql