嵌入式下C/C++调用sqlite3简单开发

本文详细介绍了如何在嵌入式系统中通过交叉编译的方式使用SQLite3,包括新建文件夹、创建测试文件、编译与运行,以及关键函数如sqlite3_open、sqlite3_close、sqlite3_exec和sqlite3_get_table的使用示例。
摘要由CSDN通过智能技术生成

交叉编译sqlite3请关注我第一篇博文

sqlite3 交叉编译-CSDN博客

sqlite3的命令的简单使用(增删改查,创建/删除表)请关注我的上一篇博文

sqlite3嵌入式使用以及C/C++代码开发-CSDN博客

一、新建文件夹

此文件夹用于放置工程,比如我的文件夹叫sqliteDemo,将交叉编译编译好的sqlite3的lib文件夹和头文件放置在工程目录下

sqliteDemo文件夹下文件如下

二、创建测试文件

创建一个c文件,比如我的为main.c

在C文件中写入如下内容

#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"

int main(void)
{
    sqlite3 *ppdb;
    int ret = sqlite3_open("student.db",&ppdb);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_open Failed -- %s\n", sqlite3_errmsg(ppdb));
        exit(1);
    }
    return 0;
}

三、编译测试

执行命令  arm-linux-gnueabihf-gcc main.c -o sql -L./lib -lsqlite3

则生成一个命令 sql 的可执行文件

四、运行

将sql拷贝到开发板中的某个位置,执行 ./sql 即可运行

五、sqlite函数说明

sqlite3库函数在其官网有对应的说明,可登录其网站查阅

SQLite Home Page

其中,introduction列出了常用的几个函数,如果想看更多函数,可查看其函数列表网页List Of SQLite Functions

对于一般想小型开发,仅需掌握如下四个函数即可:

sqlite3_open()

sqlite3_close()

sqlite3_exec()

sqlite3_get_table()

下面对最常用几个函数进行介绍

sqlite3_open()

此函数功能为创建数据库,如果数据库已经创建,则打开数据库,函数原型如下Opening A New Database Connection

filename为数据库的名字,即执行 ./sqlite3 student命令时的student这个值

ppDb为数据库句柄,后续对数据库的所有操作都通过此句柄进行传值。

使用举例:

​
sqlite3 *ppDb;

int ret = sqlite3_open("student.db", &ppDb);

if(ret != SQLITE_OK)
{ 
    printf("Open Sqlite3 Failed : %s\n",sqlite3_errmsg(ppDb));
}

​
sqlite3_close() 

此函数功能为关闭数据库,如果sqlite3对象被成功销毁并且所有相关资源都被释放,则对sqlite3_close()的调用返回SQLITE_OK。函数原型如下Closing A Database Connection

使用举例
sqlite3 *ppDb;

int ret = sqlite3_open("student.db", &ppDb);

if(ret != SQLITE_OK)
{ 
    printf("Open Sqlite3 Failed : %s\n",sqlite3_errmsg(ppDb));
}

ret = sqlite3_close(ppDb);    //关闭数据库

if(ret != SQLITE_OK)
{ 
    printf("Release Sqlite3 Failed : %s\n",sqlite3_errmsg(ppDb));
}

sqlite3_exec()

此函数为sqlite3函数的重中之重,用它可以执行几乎所有的sqlite3命令。函数原型如下One-Step Query Execution Interface

第一个参数 sqlite3*,为一个打开的数据库的句柄,比如前面sqlite3_open函数中ppDb参数。

第二个参数为填有sql的命令行语句的字符串

第三个参数为回调函数。回调函数返回值为 int。但此参数只对有显示的命令行有效,比如:select * from student命令

第四个参数为回调函数需要传入的参数,即回调函数的第一个参数值

第五个保存错误消息

使用举例一

#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"

int main(void)
{
	//打开或者创建数据库文件
	sqlite3 *ppdb;
	int ret = sqlite3_open("student.db",&ppdb);
	if(ret != SQLITE_OK)
	{
		printf("Open Sqlite Failed -- %s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	
	//创建数据表
	char *sqltCmd = "create table student (id integer, name txt, age integer);";
	ret = sqlite3_exec(ppdb, sqltCmd, NULL, NULL, NULL);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_exec1 Failed! -- %s\n", sqlite3_errmsg(ppdb));
		exit (1);
	}
	
    //再次创建数据表
	char *errmsg;
	ret = sqlite3_exec(ppdb, sqltCmd, NULL, NULL, &errmsg);	//第五个参数保存错误消息
	if(ret != SQLITE_OK)
	{
		//因为sqltCmd中的命令重复创建了数据表,所以会报错,命令行中的错误会通过errmsg指针返回
		//可以通过命令行输入两遍 sqltCmd 命令对比程序运行中的下一行打印
		printf("sqlite3_exec1 Failed! -- %s\n", sqlite3_errmsg(ppdb));
		exit (1);
	}
	
	ret = sqlite3_close(ppdb);
	if(ret != SQLITE_OK)
	{
		printf("Sqlite Release Failed -- %s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	return 0;
}

使用举例二

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"

/*
print函数每查询一行,就执行一次,故无需返回数据库的数据条数,也为行数
sql:需要传入的其它参数
colum:返回数据库的字段数,也为列数
value: 返回字段的值
name:返回字段的名称
*/
int print(void * sql, int column, char** value, char ** name)
{
	printf("第一个参数示例:%s\n",sql);
    int i;
    for(i = 0; i < column; i++)
    {
        printf("%s=%s  ", name[i], value[i]);
    }
    printf("\n");
    return 0;
}


int main(void)
{
    //创建或打开数据库
    sqlite3 *ppdb;
    int ret = sqlite3_open("student.db", &ppdb);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_open : %s\n", sqlite3_errmsg(ppdb));
        exit(1);
    }

	//创建表 student
    char* sql = "create table if not exists student (id integer, name txt, age integer);";
    ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_exec1 : %s\n", sqlite3_errmsg(ppdb));
        exit(1);
    }

    char cmd[256] = {0};
    int id, age, i;
    char name[256]={0};
    for(i = 0; i < 2; i++)
    {
        printf("请输入学号、名字和年龄:\n");
        scanf("%d%s%d",&id,name,&age);
        memset(cmd, 0, sizeof(cmd));
        sprintf(cmd,"insert into student (id, name, age) values(%d, '%s', %d);",id,name,age);
        ret = sqlite3_exec(ppdb, cmd, NULL, NULL, NULL);
        if(ret != SQLITE_OK)
        {
            printf("sqlite3_exec2 : %s\n", sqlite3_errmsg(ppdb));
            exit(1);
        }
    }
	
	memset(cmd, 0, sizeof(cmd));
	sprintf(cmd,"select * from student;");
	ret = sqlite3_exec(ppdb, cmd, print, sql, NULL);//此处sql仅仅是用来说明传参问题
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_exec3 : %s\n", sqlite3_errmsg(ppdb));
		exit(1);
	}
	
	ret = sqlite3_close(ppdb);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_close : %s\n", sqlite3_errmsg(ppdb));
		exit(1);
	}
    return 0;
}
    

执行效果如下

sqlite3_exec函数回调参数的再说明

以  使用举例二 为例,假如此时数据表中含有4项数据

在调用sqlite3_exec函数查询数据表时

每查询到一条数据,则调用一次 回调函数 print。

假如现在查询完第一条数据,即 1|aa|11 

则返回列数为 3(形参column 为 3),数据值为 1 aa 11 的字符串(即 *value 指向{"1", "aa", "11"}的字符串首地址),字段值为 id name age 的字符串(即*name 指向{"id","name","age"}的字符串的首地址)

因此,可以通过 value[i] 和 name[i] 找到对应的字符串

此函数为sqlite3专门用于查询语句的函数,函数原型如下

Convenience Routines For Running Queries

第一个参数为数据库的句柄

第二个参数为填有sql的命令行语句的字符串

第三个参数为查询后的返回值

第四个参数为查询到数据库中数据的条数(即行数)

第五个参数为查询到数据库中数据的字段数(即列数)

第三参数pazResult为一个一维数组,存放方式为    表头,表1对应的值,表2对应的值......

仍然以前面数据库为例说明

pazResult中数据存放方式如下图所述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"

int main(void)
{
    //创建或打开数据库
    sqlite3* ppdb;
    int ret = sqlite3_open("student.db",&ppdb);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_open : %s\n", sqlite3_errmsg(ppdb));
        exit(1);
    }

    char* sql = "create table student(id integer, name text, age integer);";
    ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_exec1 : %s\n", sqlite3_errmsg(ppdb));
        exit(1);
    }

    char cmd[256] = {0};
    int id, age, i, j;
    char name[128] = {0};
    for(i = 0; i < 2; i++)
    {
        printf("请输入学号、名字和年龄:\n");
        scanf("%d%s%d",&id, name, &age);
        memset(cmd, 0, sizeof(cmd));
        sprintf(cmd, "insert into student(id, name, age) values (%d, '%s', %d);",id,name,age);
        ret = sqlite3_exec(ppdb, cmd, NULL, NULL, NULL);
        if(ret != SQLITE_OK)
        {
            printf("sqlite3_exec2 : %s\n", sqlite3_errmsg(ppdb));
            exit(1);
        }
    }
    
    char **result;
    int row, column;
    memset(cmd, 0, sizeof(cmd));
    sprintf(cmd, "select * from student;");
    ret = sqlite3_get_table(ppdb, cmd, &result, &row, &column, NULL);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_get_table: %s\n", sqlite3_errmsg(ppdb));
        exit(1);
    }
	
	int Index = column;
    for(i = 0; i < row; i++)
    {
        for(j = 0; j < column; j++)
        {
            //result[j]是指的表头的三个字符串
            //result[Index]是指的实际数据,实际数据是跨过表头后从column开始的数据
            //参照上面的内存截图理解
            printf("%s=%s  ",result[j], result[Index]);
			Index++;
        }
        printf("\n");
    }

    return 0;
}

实际执行效果如图

  • 28
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值