嵌入式中如何用C语言操作sqlite3(07)

news2024/11/26 2:45:39

sqlite3编程接口非常多,对于初学者来说,我们暂时只需要掌握常用的几个函数,其他函数自然就知道如何使用了。

数据库

本篇假设数据库为my.db,有数据表student。

nonamescore
4嵌入式开发爱好者89.0

创建表格语句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary key, name text, score real);

常用函数

sqlite3_open

int   sqlite3_open(char  *path,   sqlite3 **db);
功能:
    打开sqlite数据库
参数:
 path: 数据库文件路径
 db: 指向sqlite句柄的指针,后面对数据库所有的操作都要依赖这个句柄
返回值:
 成功返回0,失败返回错误码(非零值)

sqlite3_close

int   sqlite3_close(sqlite3 *db);
功能:
 关闭sqlite数据库      
返回值:
 成功返回0,失败返回错误码
const  char  *sqlite3_errmsg(sqlite3 *db);
功能:
 打印错误信息        
返回值:
 返回错误信息

不使用回调函数执行SQL语句

sqlite3_get_table

int   sqlite3_get_table(sqlite3 *db, const  char  *sql,  char ***resultp,  int*nrow,  int *ncolumn, char **errmsg);
功能:
 执行SQL操作
参数:
 db:数据库句柄
 sql:SQL语句
 resultp:用来指向sql执行结果的指针
 nrow:满足条件的记录的数目
 ncolumn:每条记录包含的字段数目
 errmsg:错误信息指针的地址
返回值:
 成功返回0,失败返回错误码

举例

下面比如我们要显示student表中所有的数据信息,我们就可以利用sqlite3_get_table()执行语句:

select * from student

实现代码如下:

void do_show_sample(sqlite3 *db)
 {
  char **result, *errmsg;
 int nrow, ncolumn, i, j, index;

 if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
 {
  printf("error : %s\n", errmsg);
  sqlite3_free(errmsg);
 }
 index = ncolumn;
 for (i=0; i<nrow; i++)
 {
  for (j=0; j<ncolumn; j++)
  {
   printf("%-8s : %-8s\n", result[j], result[index]);   
   index++;
  }
  printf("************************\n");
 }
 sqlite3_free_table(result);
 return;
 }

假定当前的表格的数据信息如下:

nonamescore
4一口Linux77.0
5一口peng88.0
6一口wang99.0
7一口网66.0

关于这个函数中出现的这些参数的具体含义,我们可以见下图:

sqlite3编程接口非常多,对于初学者来说,我们暂时只需要掌握常用的几个函数,其他函数自然就知道如何使用了。

数据库

本篇假设数据库为my.db,有数据表student。

nonamescore
4一口Linux89.0

创建表格语句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary key, name text, score real);

常用函数

sqlite3_open

int   sqlite3_open(char  *path,   sqlite3 **db);
功能:
    打开sqlite数据库
参数:
 path: 数据库文件路径
 db: 指向sqlite句柄的指针
返回值:
 成功返回0,失败返回错误码(非零值)

sqlite3_close

int   sqlite3_close(sqlite3 *db);
功能:
 关闭sqlite数据库      
返回值:
 成功返回0,失败返回错误码
const  char  *sqlite3_errmsg(sqlite3 *db);
功能:
 打印错误信息        
返回值:
 返回错误信息

不使用回调函数执行SQL语句

sqlite3_get_table

int   sqlite3_get_table(sqlite3 *db, const  char  *sql,  char ***resultp,  int*nrow,  int *ncolumn, char **errmsg);
功能:
 执行SQL操作
参数:
 db:数据库句柄
 sql:SQL语句
 resultp:用来指向sql执行结果的指针
 nrow:满足条件的记录的数目
 ncolumn:每条记录包含的字段数目
 errmsg:错误信息指针的地址
返回值:
 成功返回0,失败返回错误码

举例

下面比如我们要显示student表中所有的数据信息,我们就可以利用sqlite3_get_table()执行语句:

select * from student

实现代码如下:

void do_show_sample(sqlite3 *db)
 {
  char **result, *errmsg;
 int nrow, ncolumn, i, j, index;

 if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
 {
  printf("error : %s\n", errmsg);
  sqlite3_free(errmsg);
 }
 index = ncolumn;
 for (i=0; i<nrow; i++)
 {
  for (j=0; j<ncolumn; j++)
  {
   printf("%-8s : %-8s\n", result[j], result[index]);   
   index++;
  }
  printf("************************\n");
 }
 sqlite3_free_table(result);
 return;
 }

假定当前的表格的数据信息如下:

nonamescore
4一口Linux77.0
5一口peng88.0
6一口wang99.0
7一口网66.0

关于这个函数中出现的这些参数的具体含义,我们可以见下图:

图片

在这里插入图片描述

由上图可知:代码中:

ncolumn = 3
nrow    = 5
result 指向所有的结果组成的字符串数组,
各个具体字符串的下标,图上已经标明。

结合此图再去理解代码,就很容易理解代码的实现原理。

使用回调函数执行SQL语句

sqlite3_exec

typedef  int (*sqlite3_callback)(void *, int, char **, char **);

int   sqlite3_exec(sqlite3 *db, const  char  *sql,  sqlite3_callback callback, void *,  char **errmsg);
功能:
 执行SQL操作
参数:
 db:数据库句柄
 sql:SQL语句,就是我们前面两章用于操作表的增删改查语句
 callback:回调函数
 errmsg:错误信息指针的地址
返回值:
 成功返回0,失败返回错误码

回调函数

typedef  int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);
功能:
 每找到一条记录自动执行一次回调函数
参数:
 para:传递给回调函数的参数
 f_num:记录中包含的字段数目
 f_value:包含每个字段值的指针数组
 f_name:包含每个字段名称的指针数组
返回值:
 成功返回0,失败返回-1

举例

sqlite3 *db;
char  *errmsg,**resultp;

int callback(void *para, int f_num, char **f_val, char **f_name)
{
 int i;

 for (i=0; i<f_num; i++)
 {
  printf("%-8s", f_val[i]);
 }
 printf("\n");

 return 0;
}

void do_show(sqlite3 *db)
{
 char *errmsg;

 printf("no      name    score\n");
 
 if (sqlite3_exec(db, "select * from student", callback, NULL, &errmsg) != 0)
 {
  printf("error : %s\n", sqlite3_errmsg(db));
 }
 printf("\n");

 return;
}

回调函数方法实现的代码,需要实现一个回调函数:callback。函数sqlite3_exec()在解析命令"select * from student" ,没获取到一行数据就会调用一次回调函数, 参考上面的表格student,

callback()总共会被调用5次,
f_num 对应结果的列数,为3
f_value 则指向 每一列对应的值组成的字符串数组

假设现在callback是第四次被调用,如下图:

图片

运行结果

编译需要使用第三方库lsqlite3。

gcc student.c -o run -lsqlite3

其他函数

sqlite3 *pdb, 数据库句柄,跟文件句柄FILE很类似
sqlite3_stmt *stmt, 这个相当于ODBC的Command对象,用于保存编译好的SQL语句

sqlite3_exec(), 执行非查询的sql语句
sqlite3_prepare(), 准备sql语句,执行select语句或者要使用parameter bind时,用这个函数(封装了sqlite3_exec)
Sqlite3_step(), 在调用sqlite3_prepare后,使用这个函数在记录集中移动

还有一系列的函数,用于从记录集字段中获取数据,如

sqlite3_column_text(), 取text类型的数据
sqlite3_column_blob(),取blob类型的数据
sqlite3_column_int(), 取int类型的数据

国际惯例,上完整代码:

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

void do_insert(sqlite3 *db)
{
 int no;
 char name[16];
 float score;
 char sqlstr[128], *errmsg;

 printf("input no : ");
 scanf("%d", &no);
 printf("input name : ");
 scanf("%s", name);
 printf("input score : ");
 scanf("%f", &score);
 sprintf(sqlstr, "insert into student values (%d, '%s', %.1f)", 
 no, name, score);
 #if __DEBUG
 printf("cmd:%s\n",sqlstr);
 #endif
 if (sqlite3_exec(db, sqlstr, NULL, NULL, &errmsg) != 0)
 {
  printf("error : %s\n", sqlite3_errmsg(db));
 }
 else
 {
  printf("insert is done\n");
 }
 printf("\n");

 return;
}

void do_delete(sqlite3 *db)
{
 char *errmsg;
 char sqlstr[128], expression[64];

 printf("input expression : ");
 scanf("%s", expression);//name='ma'
 sprintf(sqlstr, "delete from student where %s", expression);
#if __DEBUG
 printf("cmd:%s\n",sqlstr);
#endif
 if (sqlite3_exec(db, sqlstr, NULL, NULL, &errmsg) != 0)
 {
  printf("error : %s\n", sqlite3_errmsg(db));
 }
 else
 {
  printf("deletet is done\n");
 }
 printf("\n");

 return;
}
 
int callback(void *para, int f_num, char **f_val, char **f_name)
{
 int i;

 for (i=0; i<f_num; i++)
 {
  printf("%-8s", f_val[i]);
 }
 printf("\n");

 return 0;
}

void do_show(sqlite3 *db)
{
 char *errmsg;

 printf("no      name    score\n");

 if (sqlite3_exec(db, "select * from student", callback, NULL, &errmsg) != 0)
 {
  printf("error : %s\n", sqlite3_errmsg(db));
 }
 printf("\n");

 return;
}

 void do_show_sample(sqlite3 *db)
 {
  char **result, *errmsg;
 int nrow, ncolumn, i, j, index;

 if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
 {
  printf("error : %s\n", errmsg);
  sqlite3_free(errmsg);
 }
 
 index = ncolumn;

 for (i=0; i<nrow; i++)
 {
  for (j=0; j<ncolumn; j++)
  {
   printf("%-8s : %-8s\n", result[j], result[index]);
   
    
   index++;
  }
  printf("************************\n");
 }
 sqlite3_free_table(result);

 return;
 }
 

int main()
{
 sqlite3 *db;
 int n;
 char clean[64];

 if (sqlite3_open("my.db", &db) < 0)
 {
  printf("fail to sqlite3_open : %s\n", sqlite3_errmsg(db));
  return -1;
 }

 while ( 1 )
 {
  printf("*********************************************\n");
  printf("1: insert record   \n2: delete record  \n3: show record  \n4: quit\n");
  printf("*********************************************\n");
  printf("please select : "); 
  
  if (scanf("%d", &n) != 1)
  {
   fgets(clean, 64, stdin);
   printf("\n");
   continue;
  }
  switch ( n )
  {
   case 1 :
    do_insert(db);
    break;
   case 2 :
    do_delete(db);
    break;
   case 3 :
    do_show_sample(db);
    break;
   case 4 :
    sqlite3_close(db);
    exit(0);
  }
 }
 return 0;
}

运行主页面:

图片

插入记录:

图片

显示记录:

图片

删除记录:

图片

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构算法--8基数排序

> 多关键字排序&#xff1a;现在有一个员工表&#xff0c;要求按照薪资排序&#xff0c;薪资相同的员工按照年龄排序 >> 先按照年龄排序&#xff0c;再按照薪资进行稳定的排序 > 例如&#xff1a;32&#xff0c;13&#xff0c;94&#xff0c;52&#xff0c;17&am…

C++中指针的概念和声明

C中指针的概念和声明 学习 C 的指针既简单又有趣。通过指针&#xff0c;可以简化一些 C 编程任务的执行&#xff0c;还有一些任务&#xff0c;如动态内存分配&#xff0c;没有指针是无法执行的。所以&#xff0c;想要成为一名优秀的 C 程序员&#xff0c;学习指针是很有必要的…

Unity实现设计模式——责任链模式

Unity实现设计模式——责任链模式 责任链模式定义&#xff1a;将请求的发送和接收解耦&#xff0c;让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链&#xff0c;并沿着这条链传递这个请求&#xff0c;直到链上的某个接收对象能够处理它为止。 在职责链模式中&…

CIP或者EtherNET/IP中的PATH是什么含义?

目录 SegmentPATH举例 最近在学习EtherNET/IP&#xff0c;PATH不太明白&#xff0c;翻了翻规范&#xff0c;在这里记个笔记。下面的叙述可能是中英混合&#xff0c;有一些是规范中的原文我直接搬过来的。我翻译的不准确。 Segment PATH是CIP Segment中的一个分类。要了解PATH…

dataGrip导出导入的方式

导出&#xff1a;选中需要导出的表 导入&#xff1a;选中导出的sql文件

运动控制:为什么高精度的测量都是用大理石平台

一、大理石的应用场景 在一些应用直线电机的场景&#xff0c;以及一些量测性仪器仪表上面&#xff0c;我们都能看到大理石的身影&#xff0c;毫无疑问&#xff0c;只要是精度要求高的地方&#xff0c;就少不了大理石&#xff0c;这和大理石的自身特性是分不开的。 二、天然大理…

【JVM】并发可达性分析-三色标记算法

欢迎访问&#x1f44b;zjyun.cc 可达性分析 为了验证堆中的对象是否为可回收对象&#xff08;Garbage&#xff09;标记上的对象&#xff0c;即是存活的对象&#xff0c;不会被垃圾回收器回收&#xff0c;没有标记的对象会被垃圾回收器回收&#xff0c;在标记的过程中需要stop…

项目集成七牛云存储sdk

以PHP为例 第一步&#xff1a;下载sdk PHP SDK_SDK 下载_对象存储 - 七牛开发者中心 sdk下载成功之后&#xff0c;将sdk放入项目中&#xff0c;目录选择以自己项目实际情况而定。 注意&#xff1a;在examples目录中有各种上传文件的参考示例&#xff0c;这里我们主要参考的是…

Vue 实现表单的增删改查功能及表单的验证

前言&#xff1a; 上一篇我们已经将前端表单的数据和后端的数据交互了&#xff0c;今天我们就继续开发功能来实现表单的增删改查功能及表单的验证 一&#xff0c;表单的增删改查功能 新增 去官网找模版&#xff1a; 1.1添加新增按钮&#xff1a; 1.2添加新增弹窗点击事件&am…

HC32 IIC/I2C读写

IIC状态码 IIC 初始化 void iicInit(uint32_t speed) {stc_gpio_cfg_t stcGpioCfg;DDL_ZERO_STRUCT(stcGpioCfg);Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //开启GPIO时钟门控stcGpioCfg.enDir GpioDirOut; ///< 端口方向配置…

Kubernetes 上的数据已跨越鸿沟:在 GKE 上运行有状态应用程序的案例

Kubernetes 是当今云原生开发的事实上的标准。长期以来&#xff0c;Kubernetes 主要与无状态应用程序相关&#xff0c;例如 Web 和批处理应用程序。然而&#xff0c;与大多数事物一样&#xff0c;Kubernetes 也在不断发展。如今&#xff0c;我们看到 Kubernetes 上有状态应用程…

MySQL学习笔记19

MySQL日志文件&#xff1a;MySQL中我们需要了解哪些日志&#xff1f; 常见日志文件&#xff1a; 我们需要掌握错误日志、二进制日志、中继日志、慢查询日志。 错误日志&#xff1a; 作用&#xff1a;存放数据库的启动、停止和运行时的错误信息。 场景&#xff1a;用于数据库的…

ubuntu apt工具软件操作

apt工具 -----> 网关 国内网络(仓库源) 美国网络(仓库源)/etc/apt/sources.list https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/sudo apt-get update sudo apt install sl 安装包 sudo apt-cache show sl 查看包信…

Jquery 复选框全选和反选失灵的问题

页面上有这么一张表格&#xff0c;点击All时将列表中的复选框全部勾选&#xff0c;反之亦然。 表头&#xff1a; <th><input type"checkbox" id"chkAll" onclick"CheckAll(this)" />All </th> 表格数据源绑定&#xff1a; …

TouchGFX界面开发 | 项目代码结构分析

项目代码结构分析 本文介绍TouchGFX项目中TouchGFX Designer自动生成的代码&#xff0c;以及需要用户编写的扩展代码。 一、生成的代码和用户代码 TouchGFX Designer生成的代码将与用户编写的代码完全分离。 事实上&#xff0c;自动生成的代码位于generated/gui_generated文…

【DTEmpower案例操作教程】智能模型预警

DTEmpower是由天洑软件自主研发的一款通用的智能数据建模软件&#xff0c;致力于帮助工程师及工科专业学生&#xff0c;利用工业领域中的仿真、试验、测量等各类数据进行挖掘分析&#xff0c;建立高质量的数据模型&#xff0c;实现快速设计评估、实时仿真预测、系统参数预警、设…

全面解析‘’vcomp140.dll,无法继续执行代码怎么修复,解决方法分享

在我最近的一次的打开电脑软件过程中&#xff0c;我遇到了一个棘手的问题&#xff1a;我的计算机无法启动&#xff0c;系统提示找不到vcomp140.dll文件。这个文件是Windows操作系统的一个重要组件&#xff0c;如果丢失或损坏&#xff0c;可能会导致系统无法正常运行。我决定挑战…

详解 TCP 原理

TCP 一、TCP 报文协议段二、TCP 原理1、确认应答机制2、超时重传机制3、连接管理机制4、滑动窗口5、流量控制6、拥塞控制7、延时应答8、捎带应答9、面向字节流&#xff08;粘包问题&#xff09;10、异常情况&#xff08;机器掉电/网线断开&#xff1a;心跳包&#xff09; 一、T…

TouchGFX界面开发 | 按钮控件应用示例

按钮控件应用示例 按钮是最常见的部件之一&#xff0c;有了按钮就可以点击&#xff0c;从而响应事件&#xff0c;达到人机交互的目的。TouchGFX Designer内置了七种按钮部件&#xff1a; 下压按钮&#xff1a;能够在被释放时发送回调&#xff0c;按下和释放状态都关联了图像标…

AI算法+视频技术助力构建智慧城管解决方案,实现城市管理精细化

一、背景分析 物联网、大数据、移动互联网等技术的日新月异&#xff0c;城市管理对信息资源需求的日益提升&#xff0c;广大市民对政府服务新的诉求&#xff0c; 智慧城管正面临千载难逢的发展机遇。 发展历程&#xff1a; 1&#xff09;数字城管&#xff1a;城市管理机制的…