Linux嵌入式数据库

一、SQLite简介

SQLite是一个无服务器的数据库,是自包含的。这也称为嵌入式数据库,这意味着数据库引擎作为应用程序的一部分运行。特点:轻量化,易用的嵌入式数据库,用于设备端的数据管理,可以理解成单点的数据库。传统服务器型数据库用于管理多端设备,更加复杂。
MySQL需要运行服务器,MySQL将需要客户端和服务器架构通过网络进行交互。
在这里插入图片描述
基于嵌入式的数据库主要有:SQLite,Firebird,Berkeley DB,eXtremeDB
Firebird 是关系型数据库,功能强大,支持存储过程,SQL兼容等
SQLite 关系型数据库,体积小,支持ACID事务
Berkeley DB 并没有数据库服务器的概念,他的程序直接链接到应用程序中
eXtremeDB 是内存数据库,运行效率高

二、SQLite数据库安装

2.1
访问 https://www.sqlite.org/download.html
2.2 在这里插入图片描述
2.3 安装步骤

  1. 把下载的文件sqlite-autoconf-3390000.tar.gz上传到开发板
  2. tar xvf sqlite-autoconf-3390000.tar.gz 解压
  3. cd sqlite-autoconf-3390000 进入文件夹
  4. ./configure --prefix=/usr/local 配置安装路径在/usr/local
  5. make 编译
  6. sudo make install 安装

键入 sqlite3 打开数据库
在这里插入图片描述

三、SQLite的命令用法

3.1 创建一个数据库

(1) sqlite3 进入数据库 
(2)  .open test.db
(3) .quit 数据库退出后在命令当前路径创建数据库test.db
(4).databases 列出当前打开的数据库

在这里插入图片描述

3.2 创建一张表格

create table stu(id Integer,name char,score Integer);

3.3 向创建的表格中插入数据

insert into stu values(1,'huang',99); 
insert into stu values(2,"gang",100); ''""都行 
insert into stu(name,score) values("huanggang",98); 插入部分字段内容

在这里插入图片描述

3.4 查看数据库的记录

select * from stu; //查询所有字段的结果
select name,score from stu; //查询数据库中部分字段的内容

在这里插入图片描述

3.5 其他常用语句

(1)删除一条记录

delete from stu where id = 1;

(2)更改一条记录

update stu set name = 'huangg' where id = 2;

(3)删除一张表

drop table stu;

(4)增加一列

alter table stu add column sex char;

四、SQLite的编程操作

4.1 打开/创建数据库的C接口

需要引入的头文件

#include <sqlite3.h>

4.1.1打开数据库函数介绍

sqlite3_open(const char *filename, sqlite3 **ppDb) //该例程打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。 
sqlite3_close(sqlite3*)// 该例程关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。 
const char *sqlite3_errmsg(sqlite3*); 返回错误信息
int sqlite3_errcode() 通常用来获取最近调用的API接口返回的错误代码

sqlite3_open 返回值
在这里插入图片描述
4.1.2 示例代码

#include <stdio.h>
#include <sqlite3.h>
int main(char argc,char **argv)
{
    sqlite3 *db;
    int ret;

    if(argc < 2){

        printf("Please input %s xxx.db\n",argv[0]);
        return -1;
    }
    if(ret = sqlite3_open(argv[1],&db)==SQLITE_OK){

        printf("open %s ok\n",argv[1]);
    }else{

        printf("the wrong num is %d\n",ret);
        if(ret == 14){
            printf("Permission deny\n");
        }
    }
    sqlite3_close(db);
    printf("done\n");

    return 0;
}

运行结果:
在这里插入图片描述

4.2 创建表的C接口

4.2.1 执行SQL语句的函数及其回调函数
(1)sqlite3_exec函数

sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)
  • 函数说明:
    该例程提供了一个执行 SQL 命令的快捷方式,SQL 命令由 sql 参数提供,可以由多个 SQL 命令组成。
  • 参数说明:
    第一个参数 :sqlite3 是打开的数据库对象
    第二个参数:sql 需要执行的sql语句
    第三个参数:sqlite_callback 是一个回调函数用来显示SQL语句后的输出结果
    第四个参数:data 作为回调函数的第一 个参数
    第五个参数:errmsg 将被返回用来获取程序生成的任何错误。 sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。
    (2)callback函数(回调函数)
int callback(void *arg, int column_size, char *column_value[], char *column_name[])```

参数说明:
void *arg:是sqlite3_exec函数的第四个参数
column_size:数据库的字段数
column_value[]:列的值
column_name:字段名字

4.2.2 示例代码
(1)SELECT 操作

#include <stdio.h>
#include <sqlite3.h>
int callback(void *arg, int column_size, char *column_value[], char *column_name[])
{
    int i;
    for(i=0;i<column_size;i++)
    {
        printf("%s = %s\n",column_name[i],column_value[i]);
    }
    printf("===============================\n");
    return 0;

}
int main(char argc,char **argv)
{
    sqlite3 *db;
    int ret;
    char *errmsg;
    char *sql;

    if(argc < 2){

        printf("Please input %s xxx.db\n",argv[0]);
        return -1;
    }
    if(ret = sqlite3_open(argv[1],&db)==SQLITE_OK){

        printf("open %s ok\n",argv[1]);
    }else{

        printf("the wrong num is %d\n",ret);
        if(ret == 14){
            printf("Permission deny\n");
        }
    }

    //sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)
    ret = sqlite3_exec(db, "create table stu1(id Integer,name char,score Integer);",\
            callback, "context of sql", &errmsg);
    if(ret == SQLITE_OK){

        printf("create successfully\n");
    }else{
        printf("create faily the reasons :%s\n",errmsg);
    }

    sql = "insert into stu1 values(1,'zhang heng',89);"\
           "insert into stu1 values(2,'wang er',91);"\
           "insert into stu1 values(3,'li si',99);";
    ret = sqlite3_exec(db,sql,callback, "context of sql", &errmsg);
    if(ret == SQLITE_OK ){
        printf("insert ok\n");

    }else{

        printf("insert error ,the reason is %s\n",errmsg);
    }

    ret = sqlite3_exec(db,"select * from stu1;",callback, "context of sql", &errmsg);

    sqlite3_close(db);
    return 0;
}
        

在这里插入图片描述
运行结果:
在这里插入图片描述
(2)UPDATE

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
static int callback(void *data, int argc, char **argv, char **azColName){
    int i;
    
    fprintf(stderr, "%s: ", (const char*)data);//stderr – 标准错误输出设备 stderr是无缓冲的,会直接输出。

    for(i=0; i<argc; i++){
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}


int main(int argc, char* argv[]) {
    sqlite3 *db;
    char *zErrMsg = 0;
    int rc; 
    char *sql;
    const char* data = "Callback function called";
    /* Open database */
    rc = sqlite3_open("test.db", &db);
    if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        exit(0);
    }else{
        fprintf(stderr, "Opened database successfully\n");
    }
    /* Create merged SQL statement */
    sql = "UPDATE stu1 set score = 100 where id=1212;"\
           "SELECT * from stu1";
    /* Execute SQL statement */
    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
    if( rc != SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }else{
        fprintf(stdout, "Operation done successfully\n");
    }
    sqlite3_close(db);
    return 0;
}

在这里插入图片描述

(4) DELETE操作

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
static int callback(void *data, int argc, char **argv, char **azColName){
    int i;
    fprintf(stdout, "%s: ", (const char*)data);
    for(i=0; i<argc; i++){
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}
int main(int argc, char* argv[]) {
    sqlite3 *db;
    char *zErrMsg = 0;
    int rc; char *sql;
    const char* data = "Callback function called";
    /* Open database */
    rc = sqlite3_open("test.db", &db);
    if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        exit(0);
    }else{
        fprintf(stderr, "Opened database successfully\n");
    }
    /* Create merged SQL statement */
    sql = "DELETE from stu1 where id = 2;"\
           "SELECT * from stu1;"
           ;
    /* Execute SQL statement */
    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
    if( rc != SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }else{
        fprintf(stdout, "Operation done successfully\n");
    }
    sqlite3_close(db);
    return 0;
    }

在这里插入图片描述
5.SQLite小练习,与链表的相互转化

#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
#include <string.h>
struct class{
    int id;
    char name[32];
    int score;
    struct class* next;

};

void MyStrcpy(char dstStr[],char srcStr[])
{
    int i=0;                              //数组下标初始化为0 
    while(srcStr[i]!='\0')                //若取出字符不是字符串的结束标志 
    {
         dstStr[i]=srcStr[i];             //复制字符 
         i++;                             //移动下标 
    }
    dstStr[i]='\0';                     //在字符串dstStr的末尾添加字符串结束标志 
}




void printLink(struct class*point)
{
    struct class*p = point;


    while(p->next!=NULL)
    {

        p = p->next;
        printf("stu->id  = %d\n",p->id);
        printf("stu->name  = %s\n",p->name);
        printf("stu->score  = %d\n",p->score);
                                 
 }

}
/*
	头插法
*/
struct class* sqlTolink(struct class* head,struct class*stu)
{


    stu->next = head->next;
    head->next = stu;
    return head;

}

int callback(void *head, int column_size, char *column_value[], char *column_name[])
{
    int i ,size;
    size = column_size;
    static char *name;
    struct class* stu;
    char *values[3];
    head = (struct class*)head;
    stu =(struct class*)malloc(sizeof(struct class));

    for(i = 0;i<column_size;i++){
        values[i] = column_value[i];
        printf("%s = %s\n",column_name[i],column_value[i]);
    }

    //将数据库中的数据做处理,并加入链表中
    stu->id = atoi(values[0]);
    name = values[1];
    MyStrcpy(stu->name,name);//这里同字符数组存储字符串。
    stu->score = atoi(values[2]);
    head = sqlTolink(head,stu);
    return 0;

}
//将链表存放的数据放入数据库中
int linkTosql(struct class s,sqlite3* sqldb)
{
    int ret;
    char sql[128];
    char *errmsg;
    printf("in linkToqsl\n");
    printf("s.name = %s\n",s.name);
    sprintf(sql, "insert into stu1 values(%d,'%s',%d);",s.id,s.name,s.score);
    printf("after sprintf sql = %s\n",sql);
    ret = sqlite3_exec(sqldb,sql,callback, NULL, &errmsg);
    printf("after sqlite3_exec\n");
    return ret;

}
int main(char argc,char **argv)
{
    sqlite3 *db;
    int ret;
    char *errmsg;
    char *sql;

    struct class *head;

    head =(struct class*)malloc(sizeof(struct class));

    head ->next = NULL;

    struct class new;
    new.id = 4;
    MyStrcpy(new.name,"huangliu");
    new.score = 100;

    printf("the new.name = %s\n",new.name);
    if(argc < 2){

        printf("Please input %s xxx.db\n",argv[0]);
        return -1;
    }
    if(ret = sqlite3_open(argv[1],&db)==SQLITE_OK){

        printf("open %s ok\n",argv[0]);
    }else{

        printf("the wrong num is %d\n",ret);
        if(ret == 14){
            printf("Permission deny\n");
        }
    }
    ret = linkTosql(new,db);
    ret = sqlite3_exec(db,"select * from stu1;",callback,(void*)head, &errmsg);
    printf("======================================================================================\n");
    sqlite3_close(db);
    printLink(head);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值