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;
}
相关推荐
爱编程— 的小李2 分钟前
有序序列合并(c语言)
c语言·算法
混迹网络的权某6 分钟前
每天一道C语言精选编程题之求数字的每⼀位之和
c语言·开发语言·考研·算法·改行学it·1024程序员节
abandondyy1 小时前
MySQL---主从复制和读写分离
数据库·mysql
DEARM LINER2 小时前
mysql 巧妙的索引
数据库·spring boot·后端·mysql
码农幻想梦3 小时前
实验九 视图的使用
前端·数据库·oracle
影子落人间3 小时前
Oracle创建存储过程,创建定时任务
数据库·oracle
大G哥3 小时前
02、Oracle过滤和排序数据
数据库·oracle
加载中loading...4 小时前
Linux线程安全(二)条件变量实现线程同步
linux·运维·服务器·c语言·1024程序员节
Wx120不知道取啥名4 小时前
C语言之长整型有符号数与短整型有符号数转换
c语言·开发语言·单片机·mcu·算法·1024程序员节
代码吐槽菌5 小时前
基于SSM的汽车客运站管理系统【附源码】
java·开发语言·数据库·spring boot·后端·汽车