Sqlite3 stmt 机制操作

article/2025/9/19 1:29:09

 

参考文献:https://blog.csdn.net/u012351051/category_8966045.html

        sqlite 提供了SQL语句执行的函数sqlite3_exec,本文介绍的是sqlite3_stmt方式对数据库进行操作。

        官方文档以及参考资料中给出的结论:如果只是单条命令,那么 使用sqlite3_exec和sqlite3_stmt效率是一样的,但是在涉及到批量操作时,推荐使用sqlite3_stmt机制。在嵌入式软件的开发中执行效率是一个关键因素,因此更加推荐使用stmt方式对数据库进行操作。同时,stmt方式提供了更加细分的步骤,因此操作也更加灵活,在实际的开发过程中数据的方式也会更加多样,更加便利。

  • 操作步骤:

  • 数据库打开
sqlite3 * db_stmt_open(char *dbName)
{sqlite3 *db = NULL;int ret =0;ret = sqlite3_open_v2(dbName,&db,SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX ,NULL);if(ret !=SQLITE_OK){printf("db_stmt_open error!\n");return NULL;}printf("db_stmt_open successful!\n");return db;
}
  • 指令准备

        slqite3_prepare可以实现对sql语句(模板)的解析和编译,生成了可以被执行的 sql语句实例。

SQLITE_API int sqlite3_prepare_v2(sqlite3 *db,            /* Database handle */const char *zSql,       /* SQL statement, UTF-8 encoded */int nByte,              /* Maximum length of zSql in bytes. */sqlite3_stmt **ppStmt,  /* OUT: Statement handle */const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
int db_stmt_prepare(sqlite3 *db,const char *sql,sqlite3_stmt **stmt)
{int ret;ret=sqlite3_prepare_v2(db,sql,strlen(sql),stmt,NULL);return ret;
}
  •  变量绑定

        该函数可以将变量绑定到sqlite3_prepare实力话的语句中。这个函数是非常方便的一个函数,在程序的设计过程中我们不能为每一个sql语句写一个独立的函数,通常是为同类的操作封装操作接口。在sqlite的select insert等操作中可以为每个表单封装通用接口,使用sqlite3_bind函数绑定传入的参数即可。sqlite提供了多个bind函数原型。

// 绑定二进制变量
SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
// 绑定double类型变量
SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
// 绑定int类型变量
SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
// 绑定text类型(char字符串)变量
SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));

        参数:
        第一个参数:sqlite3_stmt: 准备语句变量指针。 
        第二个形参: sqlite3_stmt变量参数的序号索引值,规定最左侧的SQL参数的索引值为 1,也就是说参数索引值从1开始。
        第三个形参: 是要绑定给第2个形参指向的 变量参数的 实际值。第2个形参可以指向不同的索引值。
        第四个形参: 对于有4个形参的函数,第4个形参一般是第3个形参的长度。    
        第五个形参: 是用于BLOB和字符串绑定后的 析构函数,用于在sqlite处理完blob或字符串之后处理它,一般可以设置为NULL。

关于绑定的位置关系,举一个例子说明:

const char *sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \"VALUES (?, ?, ?, ?, ?); ";ret = db_stmt_prepare(db,sql,&stmt);if(ret == SQLITE_OK)
{sqlite3_bind_int(stmt,1,id);   // 对应第一个? 也就是id的值,是int 类型sqlite3_bind_text(stmt,2,name,-1,SQLITE_STATIC); //对应第二个? 是name的值 text类型sqlite3_bind_int(stmt,3,age);sqlite3_bind_text(stmt,4,address,-1,SQLITE_STATIC);sqlite3_bind_int(stmt,5,salary);
}
  • SQL语句执行

        sqlite3_step 函数用于执行sqlite3_prepare实例化的SQL语句,相当于sqlite3_exec的作用。

SQLITE_API int sqlite3_step(sqlite3_stmt*);

        sqlite3_step函数的参数是被实例化的sql语句,重点需要关注其返回值。 

#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */

        比较常用的返回值就上面这两个,下面做一下说明:        

        SQLITE_DONE::意味着sql语句执行完成,并且成功。

        SQLITE_ROW:表示当前的返回结果中包含一行的结果数据。

        执行select操作时若有数据返回时返回值时SQLITE_ROW,若无返回值时为SQLITE_DONE,有个别操作返回值是NULL时,sqlite3_step操作的返回值也会是SQLITE_ROW,例如:SELECT min(DataTime) FROM MYTABLE; 其中min是聚合函数,即使表为空仍要返回,因此函数中还需使用sqlite3_column_bytes()进行判断,若返回0,则表示为NULL

int db_stmt_exec(sqlite3_stmt *stmt)
{int ret;do{ret=sqlite3_step(stmt);if(ret==SQLITE_BUSY){usleep(1000);continue;}break;}while(ret==SQLITE_BUSY);return ret;
}
  • SELECT 结果获取

        在sqlite3_exec方法获取select结果时通常在callback函数中处理,在sqlite_stmt机制的处理中提供了sqlite3_count方法处理select的结果,根据数据类型的不同需要使用不同的方法,常用到的函数原型如下:

// 返回查找到的字节数
SQLITE_API int sqlite3_column_bype(sqlite3_stmt*, int iCol);
// 获取二进制数据,配合sqlite3_column_type使用
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);// 获取double类型数据
SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
// 获取int类型的数据
SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
// 获取char* 类型数据
SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

        第一个参数是被stmt实例化的sql语句,第二个指的是select结果的第几个参数,编号从0开始,同时需要注意的是在sqlite3_colum_blob函数或者二进制结果时需要提前使用sqlite3_column_bype提前获取字节数用于后期拷贝,防止数据越界。举例说明一下:

/* const char *sql = "select address from company where id = 1;"; */if(SQLITE_ROW == sqlite3_step(stmt)) {/* 获取查询到的数据的字节数 ret */ret = sqlite3_column_bytes(stmt,0);printf("select len: %d \n",ret);if(ret>0 && ret <100){/* 将查询到的数据拷贝到dataBuf中,长度为ret */        memcpy(dataBuf,sqlite3_column_blob(stmt,0),ret);      printf("select result: %s \n",dataBuf);}else{printf("select error!\n");}
}

        首先执行sqlite3_column_bytes(stmt,0)函数返回查询到的字节数,其中stmt是prepare后的select语句(select address from company where id = 1;),0指的是select到的第一个结果,例子的select语句只能返回一个结果,若去掉where id = 1,则会返回多个结果,这里的第二个参数就要感觉实际情况而定。二进制类型数据的查询方法如代码备注,需要先查询长度然后再拷贝。

  • free stmt语句,关闭数据库

        sqlite3_prepare_v2语句一定要对应一条sqlite3_finalize,sqlite3_open语句一定要对应一条sqlite3_close语句,这很好理解,malloc的空间一定要free释放掉。

/* 销毁prepare申请的stmt语句空间 */
void db_stmt_free(sqlite3_stmt *stmt)
{if(stmt!=NULL){sqlite3_finalize(stmt);}
}/* 关闭数据库 */
void db_stmt_close(sqlite3 *db)
{int ret;ret = sqlite3_close_v2(db);return ret;
}
  • 完整的sqlite执行过程 
int db_stmt_select_int(sqlite3_stmt *stmt)
{int ret = 0xEE;while (SQLITE_ROW == sqlite3_step(stmt)) {ret = sqlite3_column_int(stmt, 0);}return ret;
}int selcetConut(void)
{sqlite3 *db;sqlite3_stmt *stmt = NULL;int ret;const char *sql = "select count(*) from company;";// 打开数据库db = db_stmt_open(TestDB);// sql 语句准备,并返回指针ret = db_stmt_prepare(db,sql,&stmt);if(ret!=SQLITE_OK){// 若准备失败,销毁准备语句申请的空间db_stmt_free(stmt);printf("db_exec_prepare error!\n");ret = -1;}// 执行查找操作 sqlite3_step sqlite3_columnret = db_stmt_select_int(stmt);printf("select conut(*): %d \n",ret);// 销毁prepare申请的空间db_stmt_free(stmt);// 关闭数据库db_stmt_close(db);return ret;
}


http://chatgpt.dhexx.cn/article/clIbRLHb.shtml

相关文章

sqlite stmt

转载&#xff1a;http://www.sqlite.org/syntaxdiagrams.htm Syntax Diagrams For SQLite sql-stmt-list: References: sql-stmt See also: lang.html sql-stmt: Used by: sql-stmt-list References: alter-table-stmt analyze-stmt attach-stmt begin-st…

【STMT】判定表法

文章目录 判定表法题目解答 判定表法 判定表(Desision table)用于表示和分析复杂的逻辑关系&#xff0c;描述了在不同条件(Condition)下执行的动作(Action)集合。判定表本质上就是真值表的扩展&#xff0c;每个条件由两种可能的赋值扩展到多种可能的赋值&#xff0c;并且可以通…

MATLAB绘制折线图和散点图

折线图&#xff1a; >> a[1.3,-0.1,-0.3,0.4,0.1,-0.4,0.2,0.3,0.2,0.3,-0.1,0.5]; >> x1:1:12&#xff1b;%第一个数是起始&#xff0c;最后一个数是最后一个数据&#xff0c;第二个数是间隔 >> plot(x,a,-*)%先x轴后y轴&#xff0c;第三个是点的形状散点图…

matlab画论文实验图——01折线图(标记数据点,添加误差条)

为了减少以后画图的工作量&#xff0c;把现在画的图总结成模板&#xff0c;方便以后引用或者调整 1、基础的折线图 代码如下&#xff0c;代码有详细的注释&#xff0c;方便调整。 %linestyle,linewidth,marker&#xff0c;color等等都可以在属性里随时修改&#xff0c;这就是…

Matplotlib画折线图

Matplotlib画折线图 有一些离散点&#xff0c;想看看这些点的变动趋势&#xff1a; import matplotlib.pyplot as pltx1 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] y1[30,31,31,32,33,35,35,40,47,62,99,186,480]x2 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] y…

matlab绘制多条折线图

%绘制多条折线图 clear clc n 12; x 1:n; C 10 * rand(n,1); A 10 * rand(n,1); J 10 * rand(n,1); figure; plot(x,C,s-,x,A,s-.,x,J,s--); legend(C,A,J); 效果&#xff1a;

matlab中怎么画函数曲线,用matlab 怎么画函数曲线图

matlab的数据处理能力很强大&#xff0c;这款软件还能绘制各种函数图形。下面我将介绍用matlab画函数图形的方法&#xff0c;以在同一张图上画出y1sin(x)和y2sin^2(x)的图形为例。 工具/原料 matlab 1方法/步骤 输入自变量&#xff1a; 画已知的函数图形&#xff0c;用向量的方…

Python Matlab绘制曲线图

Python Matlab绘制曲线图 文章目录 Python Matlab绘制曲线图一、简介二、绘制图形1、第一个曲线图2、第二个图形3、第三个图形4、第四个图形 一、简介 我们在这里采用Python中的matplotlib来实现曲线图形的绘制。 二、绘制图形 1、第一个曲线图 代码&#xff1a; 具体的绘…

matlab绘制图像的直方图、杆状图和折线图等

1.imhist函数&#xff1a; himhist(f,b) 其中&#xff0c;f为输入图像&#xff0c;h是该图像的直方图数据&#xff0c;b是用来形成直方图的“容器”数目&#xff0c;即把所有灰度级分成几份的数量&#xff08;b默认为256)。若按上面一行代码中使用imhist函数&#xff0c;则并…

matlab绘制折线图

参考了别人文章画出了稍微好看一点的折线图 下面是代码 x1:1:9;%x轴上的数据&#xff0c;第一个值代表数据开始&#xff0c;第二个值代表间隔&#xff0c;第三个值代表终止 name{F1,F4,F5,F6,F8,F9,F10,F17,F18}; %横坐标字符 a[0.8201,0.6783,0.8568,0.962,0.2922,0.69,0.844…

Matlab画折线图是线型、颜色、标记符号和属性设置-LineSpec(线条设定)

说明 绘图函数接受线条设定作为参数并相应地修改生成的图形。您可以为线条指定以下三个要素&#xff1a; 线型标记符号颜色 例如&#xff1a; plot(x,y,-.or)使用点划线 (-.) 绘制 x-y 图&#xff0c;在数据点位置放置圆形标记 (o)&#xff0c;并将线条和标记设置为红色 (r…

MATLAB画曲线图

MATLAB画曲线图 新手实用|画图函数功能介绍linspaceXticksxticklabelsplot 新手实用|画图函数功能介绍 记录分享MATLAB学习过程中&#xff0c;遇到的问题及相应解决方法&#xff0c;希望能帮助到看到这篇博客的你。 linspace x1 linespace(-3,3,5); x2 -3:1.5:3;% x1 x2 …

Matlab:plot函数绘制二维折线图

一、基本调用格式 1、plot(y)   若y为向量时&#xff0c;则以y中元素序号为横坐标&#xff0c;y的分量为纵坐标绘制曲线。若y为实矩阵&#xff0c;则按照列绘制每一列对应的曲线。 2、plot(x,y)   若x和y为同维向量&#xff0c;则以x为横坐标,y为纵坐标绘制曲线。若x和y中…

MATLAB-最简单基础的画二维图(点图、折线图、拟合曲线)

之前写过一篇关于画matlab折线图的博客&#xff0c;但是写的非常潦草。也算是为了以后自己方便看&#xff0c;打算重新把画二维图部分再写一下&#xff0c;因此有了这篇博客。 画二维图形主要使用plot函数&#xff0c;使用方法说明&#xff1a;&#xff08;官网&#xff09; 1.…

MATLAB如何绘制折线图和美化折线图

MATLAB如何绘制折线图和美化折线图 MATLAB如何绘制折线图和美化折线图绘制基本图像GUI界面进行调整编写代码进行调整总结 MATLAB如何绘制折线图和美化折线图 在写论文的时候&#xff0c;我们直接用MATLAB绘制的图像和大佬的比起来总是差很远&#xff0c;现在我们来看如何美化科…

Matlab绘制多个折线图的方法

给出一个Matlab绘制折线图的例子&#xff1a;Matlab绘制多个折线图和子图的详细方法&#xff0c;并且字体设置为Times New Roman&#xff0c;可用于普通课程作业的撰写。 %% 维数选择 % 人脸1.f Dim 10:10:100; %% 数据选择 % 人脸1.f RKSH [53 68 74 77 77 78 78 78 78 78]…

MATLAB 绘制折线图

MATLAB 绘制折线图 想要绘制出如上图所示折线图&#xff0c;首先&#xff0c;先展示代码&#xff1a; x0:10:50; a[0, 1.80,7.60,17.40,31.20,49.00] plot(x,a,s-g,MarkerSize,2,MarkerFaceColor,g,MarkerEdgeColor,g,LineWidth,2); grid b[0,1.10,4.20,9.30,16.40,25.50]; ho…

MATLAB绘制统计折线图

MATLAB绘制实验数据折现图 在论文或者文章写作中&#xff0c;经常需要使用图形来表示我们的实验结果。一般来说&#xff0c;这种表示方式比表格更加直观、更加可视化。因此&#xff0c;本文给出一种使用MATLAB处理数据得到折线图的教程。 1. 待处理数据形式 待处理的数据为迭代…

MATLAB中画折线图:plot函数的简单用法

20年4月24日更新 关于MATLAB里柱状图的画法&#xff0c;以及如何在图例legend和轴标签xlabel里加入latex公式&#xff0c;请参考 https://blog.csdn.net/u014261408/article/details/102511989。 使用plot绘制二维图像 MATLAB中plot函数常常被用于绘制各种二维图像&#xff…

matlab 画折线图

针对这篇博客里有些不够详细的地方&#xff0c;后期又写了一个稍微更详细的MATLAB画折线图&#xff1a;https://blog.csdn.net/Rhiney_97/article/details/105000137 代码&#xff1a; 效果图&#xff1a; x1:1:5就是x轴上的数据&#xff0c;从1开始到5结束&#xff08;即应该有…