Linux多任务编程(网络编程-数据库篇)

前言

本文记录嵌入式领域用的小型数据库 sqlite数据库,以及c语言中使用sqlite3。

数据库

数据存储方式(3种)

(1)直接地址存储:单片机的烧写;

(2)文件存储:应用与数据之间没有特殊的联系,且数据量不太大,一行可以代表一个独立的数据;

(3)数据库存储:数据量大,且数据之间有特殊联系(可进行增删改查等等)。

  • 大型数据库:oracle
    特点:能处理上亿的数据量,一般应用于银行,通信大型的场景;
    缺点:贵,占用内存较大,GB到TB级
  • 中型数据库:mysql、SQLserver
    特点:能处理百万级的数据量,比大型数据库便宜
  • 小型数据库:sqlite(多应用在嵌入式领域)
    特点:开源,占用内存小,一般几k
  • 云数据库:百度云、阿里云、华为云等。

sqlite数据库

安装

bash 复制代码
sudo apt install sqlite3
查看是否安装成功
sqlite3 --version
安装sqlite3开发库
sudo apt-get install libsqlite3-dev

打开

没有创建数据库,有打开

bash 复制代码
sqlite3 my.db

退出

bash 复制代码
.q

SQL语句

创建数据表

sql 复制代码
create table 表名 (字段名1 字段类型1,...)
integer 整型
varchar 字符串类型,相当于一个字符数组,默认长度为50
例子:
create table stu_info (
    number integer,
    name varchar(10),
    age integer,
    sex varchar(10)
);

查看数据表

sql 复制代码
.table

删除表

sql 复制代码
drop table 表名;

插入记录(重点)

sql 复制代码
insert into 表名 values(字段值1,字段值2);
insert into stu_info values(1001,'zhangsan',18,'nan');
--插入部分数据
insert into stu_info(number,name) values(1001,'zhangsan');

查询记录(重点)

sql 复制代码
--查询所有数据
select * from 表名;
--查询某个字段
select name,age from 表明;
--按顺序输出所有记录,按数学成绩排序
select * from score_info order by math;    --默认是升序
select * from score_info order by math desc;    --加上desc变为降序排列
--多条件插叙
使用and或者or
--统计数据的条数
select count(*) from score_info;
--统计数学成绩的总和
select sum(math) from score_info;
--统计数学成绩的平均值
select avg(math) from score_info;

sqlite格式化:

sql 复制代码
.header on    显示表头
.mode column  左对齐

格式化前 :

格式化后:

案例

删除记录(重点)

sql 复制代码
--删除表中所有记录
delete from 表名;    
 --删除符合删除条件的记录
delete from 表名 where 条件;   

修改记录(重点)

sql 复制代码
update 表名 set 待修改字段名 = 修改后的值 where 条件;
--修改stu_info表中,把李四名字改为lishuang
update stu_info set name = 'lishuang' where name = '李四';

通过脚本执行SQL语句

sql 复制代码
--执行脚本 test.sql
create table shell_info (number integer,name varchar(20),cnt integer);
insert into shell_info values(1001,'zhangsan',20);
insert into shell_info values(1002,'lisi',10);
insert into shell_info values(1003,'sunwukong',9);
insert into shell_info values(1004,'wangermazi',7);

(1)将sql语句放到一个后缀.sql的文本里

(2)执行sqlite3 my.db < test.sql 导入到数据库中

多表联合查询

sql 复制代码
--查询学生信息表中学生名,以及成绩表中的数学成绩
select stu_info.name,score_info.math
from stu_info,score_info
where stu_info.number = score_info.number;

代码操作数据库

打开数据库(sqlite3_open函数)

cpp 复制代码
#include <sqlite3.h>
int sqlite3_open(const char* fileName, sqlite3** ppDB);

功能:打开数据库,不存在则先创建在打开

参数1:数据文件的路径

参数2:需要准备sqlite3*类型变量,将变量的地址作为参数,函数运行完后,此指针指向打开的数据库。

返回值:成功,返回SQLITE_OK;失败,返回其他值

执行数据库操作的SQL语句(sqlite3_exec函数)

cpp 复制代码
int sqlite3_exec(sqlite3 *, const char *sql, 
                int (*callback)(void *, int, char **, char **), 
                void *, char **errmsg);

功能:(insert into、create table、update、delete)

参数1:sqlite3* db

参数2:待执行的SQL语句(字符串)

参数3:NULL

参数4:NULL

参数5:如果SQL语句有语法错误,则将错误原因复制给此变量(字符串)

返回值:成功,返回SQLITE_OK;失败,返回其他值

例子

cpp 复制代码
#include <sqlite3.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
    sqlite3 *db;
    int ret = sqlite3_open("my.db", &db);
    if (ret == SQLITE_OK)
    {
        printf("open success\n");
        char *sql = "inset into stu_info values(1004,'xiaobai',18,'nv');";
        char *err;
        ret = sqlite3_exec(db, sql, NULL, NULL, &err);
        if (ret == SQLITE_OK)
        {
            printf("insert ok\n");
        }
        else
        {
            printf("sql:%s err:%s\n", sql, err);
        }
    }
    return 0;
}

编译时需要链接 -lsqlite3

例子2:终端输入值的方式

cpp 复制代码
#include <sqlite3.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
    sqlite3 *db;
    int ret = sqlite3_open("my.db", &db);
    if (ret == SQLITE_OK)
    {
        printf("open success\n");
        int number;
        char name[20];
        int age;
        char sex[10];
        printf("please input number,name,age,sex\n");
        scanf("%d%s%d%s",&number,name,&age,sex);
        char sql[128];
        sprintf(sql,"insert into stu_info values(%d,'%s',%d,'%s');",number,name,age,sex);
        //char *sql = "insert into stu_info values(1004,'xiaobai',18,'nv');";
        char *err;
        ret = sqlite3_exec(db, sql, NULL, NULL, &err);
        if (ret == SQLITE_OK)
        {
            printf("insert ok\n");
        }
        else
        {
            printf("sql:%s err:%s\n", sql, err);
        }
    }
    return 0;
}

查询语句(sqlite3_get_table函数)

cpp 复制代码
int sqlite3_get_table(sqlite3 *db, const char *zSql, 
                    char ***pazResult, int *pnRow, 
                    int *pnColumn, char **pzErrmsg);

参数1:db

参数2:执行的SQL语句

参数3:(出参)查询后,将查询结果(字符串数组)的首地址(char**)赋值给这个变量

参数4:(出参)有几条记录,返回的字符串数组中会把表头返回出来,但表头不不计入记录数;所以在使用此变量是,需要自行加1

参数5:(出参)有几个字段(列)

参数6:如果SQL语句有语法错误,则将错误原因复制给此变量(字符串)

cpp 复制代码
#include <sqlite3.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
    sqlite3 *db;
    int ret = sqlite3_open("my.db", &db);
    if (ret == SQLITE_OK)
    {
        printf("open success\n");
        char *sql = "select * from stu_info";
        char **q;
        int nrow, ncol;
        char *err;
        ret = sqlite3_get_table(db, sql, &q, &nrow, &ncol, &err);
        if (ret == SQLITE_OK)
        {
            if (nrow > 0) // 查询后有记录
            {
                for (int i = 0; i < nrow+1; i++)
                {
                    for (int j = 0; j < ncol; j++)
                    {
                        printf("%10s\t", *q++);
                    }
                    printf("\n");
                }
            }
        }
    }
    return 0;
}
相关推荐
LaoZhangGong1233 分钟前
STM32的“Unique device ID“能否修改?
c语言·经验分享·stm32·单片机·嵌入式硬件
RainbowSea10 分钟前
9-1. MySQL 性能分析工具的使用——last\_query\_cost,慢查询日志
数据库·sql·mysql
Sui_Network25 分钟前
Sui 如何支持各种类型的 Web3 游戏
大数据·数据库·人工智能·游戏·web3·区块链
ZKNOW甄知科技1 小时前
IT服务运营管理体系的常用方法论与实践指南(上)
大数据·数据库·人工智能
黄雪超2 小时前
深入HBase——核心组件
数据结构·数据库·hbase
让我们一起加油好吗2 小时前
【排序算法】六大比较类排序算法——插入排序、选择排序、冒泡排序、希尔排序、快速排序、归并排序【详解】
c语言·算法·排序算法
qq_529835353 小时前
Redis作为缓存和数据库的数据一致性问题
数据库·redis·缓存
老猿讲编程5 小时前
安全C语言编码规范概述
c语言·开发语言·安全
山猪打不过家猪8 小时前
ASP.NET Core Clean Architecture
java·数据库·asp.net
qwy7152292581639 小时前
13-R数据重塑
服务器·数据库·r语言