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;
}
相关推荐
2401_8576835410 小时前
为你的Python脚本添加图形界面(GUI)
jvm·数据库·python
云小逸10 小时前
【Nmap 设备类型识别技术】整体概况
服务器·c语言·网络·c++·nmap
m0_7066532310 小时前
使用Python自动收发邮件
jvm·数据库·python
梵刹古音10 小时前
【C语言】 跳转语句
c语言·开发语言·算法
松涛和鸣10 小时前
DAY67 IMX6 Development Board Configuration from Scratch
数据库·postgresql·sqlserver
路由侠内网穿透.11 小时前
fnOS 飞牛云 NAS 本地部署私人影视库 MoonTV 并实现外部访问
运维·服务器·网络·数据库·网络协议
怣5011 小时前
MySQL表筛选分组全解析:排序、分组与限制的艺术
数据库·mysql
tsyjjOvO11 小时前
JDBC(Java Database Connectivity)
java·数据库
陌上丨11 小时前
如何保证Redis缓存和数据库数据的一致性?
数据库·redis·缓存
l1t11 小时前
一个用postgresql的自定义函数求解数独的程序
数据库·postgresql·数独