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

交叉编译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_get_table

此函数为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;
}

实际执行效果如图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/490989.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

工作多年,如何从 CRUD Boy 转型为分布式系统架构师?解锁分布式系统的艺术:从零开始理解分布式系统架构与设计原理!...

编程是一门艺术&#xff0c;它的魅力在于创造。 65 哥已经工作5年了&#xff0c;一直做着简单重复的编程工作&#xff0c;活活熬成了一个只会 CRUD 的打工 boy。 65 哥&#xff1a;总是听大佬讲分布式分布式&#xff0c;什么才是分布式系统呢&#xff1f; 分布式系统是一个硬件…

环境影响与碳排放生命周期评估应用及案例分析

生命周期分析 (Life Cycle Analysis, LCA) 是评价一个产品系统生命周期整个阶段——从原材料的提取和加工&#xff0c;到产品生产、包装、市场营销、使用、再使用和产品维护&#xff0c;直至再循环和最终废物处置——的环境影响的工具。这种方法被认为是一种“从摇篮到坟墓”的…

R语言实现——网状 Meta 分析

近来年&#xff0c;网状 Meta 分析相关研究不断涌现&#xff0c;此类研究不但能发表在国内各大核心期刊上&#xff0c;还能在SCI期刊甚至医学4大刊上看到其身影。随手在pubmed上面一搜索&#xff0c;就能得到一万多篇相关文献。俨然成为医学文献研究的“大杀器”&#xff01; P…

是德科技KEYSIGHT E5071C网络分析仪

181/2461/8938产品概述&#xff1a; Keysight E5071C&#xff08;安捷伦&#xff09;网络分析仪提供同类产品中最高的射频性能和最快的速度&#xff0c;并具有宽频率范围和多功能功能。E5071C 是制造和研发工程师评估频率范围高达 20 GHz 的射频元件和电路的理想解决方案。 有…

Ansys Speos | Light Expert Group探测器组使用技巧

附件下载 联系工作人员获取附件 概述 相机挡板的设计需要在光路的不同位置同步多个照度图&#xff0c;以尽量减少杂散光。2023R2 Speos提供了一种新的探测器&#xff0c;用于高阶杂散光分析&#xff0c;可以同时对多个探测器进行光线追迹。Light Expert工具可以即时过滤3D视…

Linux:部署达梦数据库DM8(1)

0.安装DM8数据库安装包 产品下载-达梦数据 (dameng.com)https://www.dameng.com/list_103.html进入官方网站下载centos7的安装包&#xff0c;本章使用centos7进行部署&#xff0c;提前关闭好防火墙和selinux 建议你的系统运行内存为&#xff1a;2G或以上 1.部署基础环境 先安…

iOS——【CGD】

GCD 什么是GCD GCD指的是Grand Central Dispatch&#xff0c;它是苹果公司开发的一套多线程编程技术。GCD提供了一种简单而有效的方式来管理应用程序中的并发任务。它通过将任务提交到适当的队列&#xff08;串行队列或并发队列&#xff09;来管理并发执行的任务&#xff0c;…

MQTT.fx和MQTTX 链接ONENET物联网提示账户或者密码错误

参考MQTT.fx和MQTTX 链接ONENET物联网开发平台避坑细节干货。_mqttx和mqttfx-CSDN博客 在输入password和username后还是提示错误&#xff0c;是因为在使用token的时候&#xff0c;key填写错误&#xff0c;将设备的密钥填入key中

【javaWeb 第四篇】后端-Maven详细入门教程

Maven入门教程 前言Maven配置Maven依赖管理Maven的生命周期 前言 本文是作者通过学习过程中的学习笔记&#xff0c;希望帮助大家&#xff0c;同时大家可以搭配黑马程序员进行学习 Maven配置 Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具…

Day48:WEB攻防-PHP应用文件上传中间件CVE解析第三方编辑器已知CMS漏洞

目录 PHP/ASP-中间件-上传相关-IIS&Apache&Nginx(解析漏洞) IIS Apache Nginx PHP-编辑器-上传相关-第三方处理引用 PHP-CMS源码-上传相关-已知识别到利用 知识点&#xff1a; 1、PHP-中间件-文件上传-CVE&配置解析 2、PHP-编辑器-文件上传-第三方引用安全 3…

单链表增序排列节点(单链表算法库拓展v2.0)

对单链表中元素进行排序(至少有2个数据节点) /************************************************** (13)函数名:LinkList_sorting 功 能:对单链表中元素进行排序(至少有2个数据节点) 参 数:LinkList *&L:要进行排序的单链表 注意: ① 空表,或者只有一个数据节点,则不需要…

企业级快速开发框架 nbsaas-boot 1.1.8-2024 发布了

<parent><groupId>com.nbsaas.boot</groupId><artifactId>nbsaas-boot</artifactId><version>1.1.8-2024</version> </parent> 本次更新内容 1. 重构代码生成器&#xff0c;采用类提取和字段提取两种方式&#xff0c;提取功能…

查看 Debian 系统版本的 6 种方式

本篇文章将为大家介绍 6 种查看 Dibian 系统发行版本号的方式。 1. 使用 lsb_release 命令 lsb_release 命令可用于查看 Linux 发行版操作系统的具体版本。它可能尚未安装在你的操作系统中&#xff0c;因此你需要先安装它。运行以下命令来安装 lsb_release&#xff1a; apt-…

云原生靶场kebernetesGoat、Metarget

靶场 文章目录 靶场kebernetesGoat靶场安装Docker in DockerSSRF漏洞容器逃逸到主系统Docker CIS 基线分析Kubernetes CIS 安全基线分析分析被部署挖矿软件的容器镜像获取环境信息Hidden in layersRBAC最低权限配置错误使用 Sysdig Falco 进行运行时安全监控和检测 Metarget ke…

MT6762_联发科MTK6762安卓核心板规格参数

MTK6762核心板是一款集成了蓝牙、fm、wlan和gps模块的高度集成基带平台&#xff0c;为LTE/LTE-A和C2K智能手机应用程序提供支持。该安卓核心板集成了ARM Cortex-A53处理器&#xff0c;工作频率可达2.0GHz&#xff0c;并且还集成了功能强大的多标准视频编解码器。除此之外&#…

VScode 内存溢出 yarn/npm内存溢出问题解决

当前目录下执行 increase-memory-limit 然后再启动

优化卡顿实力派,品质表现更出彩

游戏卡顿无疑是开发者最需要关注的重要性能问题之一。它影响玩家的游戏进程&#xff0c;并直接对玩家的游戏体验产生不良的影响。为助力开发者应对这一难题&#xff0c;在之前的版本中&#xff0c;卡顿分析页已经陆续推出了重点函数分析、卡顿点分析以及Timeline等功能&#xf…

C# wpf 嵌入winform控件

WPF Hwnd窗口互操作系列 第一章 嵌入Hwnd窗口 第二章 嵌入WinForm控件&#xff08;本章&#xff09; 第三章 嵌入WPF控件 文章目录 WPF Hwnd窗口互操作系列前言一、导入WinForm1、.Net Framwork&#xff08;1&#xff09;、右键添加引用&#xff08;2&#xff09;、勾选程序集…

DMA知识

提示&#xff1a;文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问&#xff1a; 本文目标&#xff1a; 一、背景 2024年3月26日23:32:43 今天看了DMA存储器到存储器的DMA传输和存储器到外设的DMA实验&#xff0c;在keil仿真可以看到效果。还没有在protues和开发…

Spire.PDF for .NET【文档操作】演示:查找并删除 PDF 中的空白页

PDF 中的空白页并不罕见&#xff0c;因为它们可能是作者故意留下的或在操作文档时意外添加的。当您阅读或打印文档时&#xff0c;这些空白页可能会很烦人&#xff0c;因此可能非常有必要将其删除。在本文中&#xff0c;您将了解如何使用Spire.PDF for .NET以编程方式查找和删除…