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;
}
相关推荐
gma99910 分钟前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️13 分钟前
华为ASP与CSP是什么?
服务器·前端·数据库
Yz98761 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
苏-言1 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
Ljw...1 小时前
索引(MySQL)
数据库·mysql·索引
菠萝咕噜肉i1 小时前
超详细:Redis分布式锁
数据库·redis·分布式·缓存·分布式锁
长风清留扬1 小时前
一篇文章了解何为 “大数据治理“ 理论与实践
大数据·数据库·面试·数据治理
OpsEye2 小时前
MySQL 8.0.40版本自动升级异常的预警提示
数据库·mysql·数据库升级
Ljw...2 小时前
表的增删改查(MySQL)
数据库·后端·mysql·表的增删查改
qystca2 小时前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法