SQLiteC/C++接口详细介绍sqlite3_stmt类(二)

返回目录:SQLite—免费开源数据库系列文章目录   

上一篇:SQLiteC/C++接口详细介绍sqlite3_stmt类简介

下一篇:SQLiteC/C++接口详细介绍sqlite3_stmt类(三)

sqlite3_reset()

功能:重置一个准备好执行的SQL语句的状态,使其可以重复执行或进行新的绑定。

在SQLite3准备执行一个SQL语句之前,需要进行一系列的准备工作,包括将SQL语句编译成字节码、执行查询计划等等,这些准备工作都会影响SQL语句的执行效率。如果希望对同一个SQL语句进行多次执行,每次都重新进行这些准备工作是非常浪费时间和资源的,因此我们可以使用sqlite3_reset()函数来重置一个准备好执行的SQL语句的状态,以实现多次执行同一个SQL语句的效果。

sqlite3_reset()函数的原型定义如下:

int sqlite3_reset(sqlite3_stmt *pStmt);

函数的参数是一个sqlite3_stmt类型的指针,它是由sqlite3_prepare_v2()或sqlite3_prepare()等函数返回的sqlite3_stmt类型的准备好的语句。函数返回值为一个整型,表示函数的执行状态,成功则返回SQLITE_OK,否则返回错误代码。

下面是一个使用sqlite3_reset()的简单示例:

#include <sqlite3.h>
#include <stdio.h>
int main() {sqlite3 *db;sqlite3_stmt *stmt;const char *tail;char *err_msg = 0;sqlite3_open(":memory:", &db);sqlite3_prepare_v2(db, "SELECT 1", -1, &stmt, &tail);printf("%d\n", sqlite3_step(stmt));  // 输出1printf("%d\n", sqlite3_step(stmt));  // 输出101,再次执行SQL语句sqlite3_reset(stmt);printf("%d\n", sqlite3_step(stmt));  // 再次输出1sqlite3_finalize(stmt);sqlite3_close(db);return 0;
}

以上示例首先使用sqlite3_prepare_v2()函数将SQL语句“SELECT 1”编译成字节码并准备好执行,接着使用sqlite3_step()函数执行SQL语句并输出结果。再次调用sqlite3_step()函数会导致返回101的错误代码,因为SQL语句已经执行完毕且无法再次执行。接下来,使用sqlite3_reset()函数重置SQL语句的状态,使其可以重新执行。最后使用sqlite3_finalize()函数清理sqlite3_stmt对象并关闭数据库连接。

注意:sqlite3_reset()仅重置SQL语句的状态,包括其绑定参数、计数器和游标位置等等,不会清除上一次查询的结果数据,需要使用sqlite3_clear_bindings()函数清除之前的参数绑定。

sqlite3_finalize

使用完sqlite3stmt之后清理预处理语句占用的资源。
sqlite3_finalize函数的声明如下:

int sqlite3_finalize(sqlite3_stmt *pStmt);

sqlite3stmt是一个预处理语句的指针,在使用完sqlite3stmt之后,使用sqlite3finalize来释放占用的资源,返回值为SQLITEOK代表操作成功,SQLITEBUSY代表sqlite3stmt连接正在被其他线程使用,SQLITE_ERROR代表出现其他错误。
sqlite3finalize的作用是结束一个预处理语句的执行,调用该函数会释放sqlite3stmt结构体占用的内存。在使用完sqlite3stmt之后,使用sqlite3finalize进行清理是非常重要的,它可以释放sqlite3stmt连接占用的资源,并且可以检查语法错误等问题,比如程序是否忘记释放sqlite3stmt导致程序内存泄漏等情况。
以下是一个使用sqlite3_finalize的示例:

#include <stdio.h>
#include <sqlite3.h>
int main(void) {sqlite3 *db;char *zErrMsg = 0;int rc;const char *sql;rc = sqlite3_open(":memory:", &db);sql = "CREATE TABLE PERSON(ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL);";rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg);if (rc != SQLITE_OK) {fprintf(stderr, "SQL error: %s", zErrMsg);sqlite3_free(zErrMsg);}sqlite3_stmt *stmt;sql = "INSERT INTO PERSON(ID, NAME, AGE) VALUES(1, 'John', 25);";rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);if (rc != SQLITE_OK) {fprintf(stderr, "SQL error: %s", zErrMsg);sqlite3_free(zErrMsg);}rc = sqlite3_step(stmt);if (rc != SQLITE_DONE) {fprintf(stderr, "Execution Failed: %s\n", sqlite3_errmsg(db));}sqlite3_finalize(stmt);sqlite3_close(db);return 0;
}

以上示例程序首先通过sqlite3open()函数打开一个内存数据库,创建一个名为PERSON的表。接着使用sqlite3preparev2()函数在表中插入一条数据。在数据插入完毕后,使用sqlite3finalize()函数释放sqlite3stmt结构体占用的内存。然后,使用sqlite3close()函数关闭数据库。
可以看到,示例程序使用sqlite3finalize()函数结束sqlite3stmt结构体,以释放内存,并保证我们不会出现内存泄漏的情况。

sqlite3_prepare类

在SQLite3的C语言API中,有多个版本的sqlite3_prepare函数,包括sqlite3_prepare、sqlite3_prepare16、sqlite3_prepare16_v2、sqlite3_prepare16_v3、sqlite3_prepare_v2和sqlite3_prepare_v3函数。它们都被用于编译SQL语句为字节码,为后续的查询执行做准备,并返回准备好的语句的sqlite3_stmt对象的指针。

1、sqlite3_prepare函数
int sqlite3_prepare(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 */
);

该函数用于对SQL语句进行编译,生成SQLite的字节码。其中,db是数据库句柄,zSql是要编译的SQL语句,nByte是SQL语句的长度,ppStmt是sqlite3_stmt的指针的指针,它在函数运行成功后将指向一个sqlite3_stmt对象,包含与此SQL语句执行相关的信息,如参数和结果集的列数。pzTail指向SQL语句中未编译的部分的第一个字符的指针。

2. sqlite3_prepare16和sqlite3_prepare16_v2函数
int sqlite3_prepare16(sqlite3* db,                   /* Database handle */const void* zSql,              /* SQL statement, UTF-16 encoded */int nByte,                     /* Maximum length of zSql in bytes. */sqlite3_stmt** ppStmt,         /* OUT: Statement handle */const void** pzTail            /* OUT: Pointer to unused portion of zSql */
);
int sqlite3_prepare16_v2(sqlite3* db,                   /* Database handle */const void* zSql,              /* SQL statement, UTF-16 encoded */int nByte,                     /* Maximum length of zSql in bytes. */sqlite3_stmt** ppStmt,         /* OUT: Statement handle */const void** pzTail            /* OUT: Pointer to unused portion of zSql */int *pnReserved                /* Reserved for future use */
);

这两个函数与sqlite3_prepare函数类似,用于编译SQL语句,区别在于zSql是UTF-16编码的SQL语句。

3. sqlite3_prepare16_v3函数
int sqlite3_prepare16_v3(sqlite3* db,                   /* Database handle */const void* zSql,              /* SQL statement, UTF-16 encoded */int nByte,                     /* Maximum length of zSql in bytes. */unsigned int prepFlags,        /* Zero or more SQLITE_PREPARE_* flags */sqlite3_stmt** ppStmt,         /* OUT: Statement handle */const void** pzTail            /* OUT: Pointer to unused portion of zSql */int *pnReserved                /* Reserved for future use */
);

该函数与sqlite3_prepare16_v2函数类似,不同之处在于多了一个prepFlags参数,这个参数是用于控制编译过程的属性,如 SQLITE_PREPARE_PERSISTENT、SQLITE_PREPARE_NO_VTAB、 SQLITE_PREPARE_DESERIALIZED 等。

4. sqlite3_prepare_v2函数和sqlite3_prepare_v3函数
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 sqlite3_prepare_v3(sqlite3 *db,             /* Database handle */ const char *zSql,        /* SQL statement, UTF-8 encoded */ int nByte,               /* Maximum length of zSql in bytes. */ unsigned int prepFlags,  /* Zero or more SQLITE_PREPARE_* flags */ sqlite3_stmt **ppStmt,   /* OUT: Statement handle */ const char **pzTail      /* OUT: Pointer to unused portion of zSql */ 
);

这两个函数也是用于编译SQL语句,ppStmt参数返回一个sqlite3_stmt结构体指针,pzTail参数类似 sqlite3_prepare16_v3的 pzTail参数,它用于存放未被编译的 SQL 语句字符(UTF-8编码)位置。因为sqlite3_prepare_v2和sqlite3_prepare_v3函数使用UTF-8编码,而sqlite3_prepare、sqlite3_prepare16、sqlite3_prepare16_v2、sqlite3_prepare16_v3函数使用UTF-16编码。

以上是SQLite3 C语言API中的6种预处理函数,它们用于编译SQL语句,生成SQLite的字节码,为后续的查询执行做准备,并返回准备好的语句的sqlite3_stmt对象的指针。其中,选择哪一个预处理函数取决于需求的功能和SQL语句编码格式。

以下是一个使用SQLite3 C语言API中的sqlite3_prepare_v2函数编译SQL语句的示例:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
int main(void) {sqlite3 *db;char *err_msg = 0;int rc = sqlite3_open("example.db", &db);if (rc != SQLITE_OK) {fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}const char *sql = "SELECT * FROM person";sqlite3_stmt *stmt;rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);if (rc != SQLITE_OK) {fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}while (sqlite3_step(stmt) == SQLITE_ROW) {int id = sqlite3_column_int(stmt, 0);char *name = (char *)sqlite3_column_text(stmt, 1);int age = sqlite3_column_int(stmt, 2);printf("ID = %d, NAME = %s, AGE = %d\n", id, name, age);}sqlite3_finalize(stmt);sqlite3_close(db);return 0;
}


该示例程序首先使用sqlite3_open()函数打开名为"example.db"的数据库。接着,使用sqlite3_prepare_v2()函数编译一个查询语句,并返回一个sqlite3_stmt对象的指针,包含与此SQL语句执行相关的信息。然后,使用sqlite3_step()函数遍历结果集,使用sqlite3_column_xxx()函数获取结果集中的每一行数据。最后,使用sqlite3_finalize()函数释放sqlite3_stmt结构体占用的内存,并使用sqlite3_close()函数关闭数据库。

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

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

相关文章

跨越时空的纽带:探索Facebook如何连接人与人

引言 Facebook作为全球最大的社交媒体平台之一&#xff0c;已经成为了人们日常生活中不可或缺的一部分。它不仅仅是一个社交网络&#xff0c;更是连接人与人、人与世界的纽带。在这篇文章中&#xff0c;我们将深入探讨Facebook如何跨越时空&#xff0c;连接人与人之间的关系&a…

Idea 不能创建JDK1.8的spring boot项目

由于https://start.springboot.io/ 不支持JDK1.8&#xff0c;那么我们需要换idea的springboot创建源&#xff0c;需要换成 https://start.aliyun.com&#xff0c;这也是网上大部分教程说的&#xff0c;但是我这边会报这样的错误&#xff1a; Initialization failed for https:…

Linux/Monitored

Enumeration nmap 用 nmap 扫描了常见的端口&#xff0c;发现对外开放了 22,80,389,443,5667 端口&#xff0c;端口详细信息如下 ┌──(kali㉿kali)-[~/vegetable/HTB/Monitored] └─$ nmap -sC -sV -p 22,80,389,443,5667 10.10.11.248 Starting Nmap 7.93 ( https://nm…

《论文阅读》带边界调整的联合约束学习用于情感原因对提取 ACL 2023

《论文阅读》带边界调整的联合约束学习用于情感原因对提取 前言简介Clause EncoderJoint Constrained LearningBoundary Adjusting损失函数前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《Joint Cons…

音频和视频标签

音频用audio标签 controls表示控制栏 loop循环播放音频 autoplay自动播放&#xff08;浏览器基于隐私一般不支持&#xff09; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Com…

UDP客户端与服务端执行bind和connect

udp服务器使用connect()函数指明套接字的目的地址/端口号&#xff0c;使服务器只接受特定主机的请求&#xff1b; udp服务器调用了bind()函数为服务器套接字绑定本地地址/端口&#xff0c;使得客户端知道发数据的目的地址/端口&#xff1b; udp客户端调用connect()函数指明目的…

ubuntu10.04 apache2.2开启tls1.2的支持,使现代的edge和firefox浏览器能正常访问https

最近发现自己ubuntu10.04服务器上的apache https无法通过win11上的edge和firefox浏览器访问&#xff0c;但xp下的ie6和ie8没有问题。 firefox的错误提示为“此网站可能不支持TLS 1.2协议,而这是Firefox支持的最低版本”。 经过检查发现&#xff1a; IE6访问https所需的版本是SS…

时序预测 | Matlab实现BiTCN-BiLSTM双向时间卷积神经网络结合双向长短期记忆神经网络时间序列预测

时序预测 | Matlab实现BiTCN-BiLSTM双向时间卷积神经网络结合双向长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现BiTCN-BiLSTM双向时间卷积神经网络结合双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现BiTCN…

ASP .Net Core ILogger日志服务

&#x1f433;简介 ILogger日志服务是.NET平台中的一个内置服务&#xff0c;主要用于应用程序的日志记录。它提供了灵活的日志记录机制&#xff0c;允许开发者在应用程序中轻松地添加日志功能。以下是其主要特点和组件&#xff1a; ILogger接口&#xff1a;这是ILogger日志服…

【Vue】三、使用ElementUI实现图片上传

目录 一、前端代码实现 二、后端代码实现 三、调试效果实现 一、前端代码实现 废话不多说直接上代码 <el-form-item prop"image" label"上传图片" v-model"form.image"><el-upload:action"http://localhost:8…

【C语言】循环语句(语句使用建议)

文章目录 **while循环****while循环的实践****补充:if语句与while语句区别****for循环(使用频率最高)****for循环的实践****while循环和for循环的对比****Do-while循环****break和continue语句****循环的嵌套****goto语句(不常用)****循环语句的效率(来自于高质量的C/C编程书籍…

nRF Sniffer在wireshark下的环境搭建

一、准备 nRF Sinffer 安装包&#xff1a; 直接下载&#xff1a;https://nsscprodmedia.blob.core.windows.net/prod/software-and-other-downloads/desktop-software/nrf-sniffer/sw/nrf_sniffer_for_bluetooth_le_4.1.1.zip 官网下载&#xff1a; nRF Sniffer for Bluetooth…

webpack中常见的Plugin?解决了什么问题?

一、是什么 Plugin&#xff08;Plug-in&#xff09;是一种计算机应用程序&#xff0c;它和主应用程序互相交互&#xff0c;以提供特定的功能 是一种遵循一定规范的应用程序接口编写出来的程序&#xff0c;只能运行在程序规定的系统下&#xff0c;因为其需要调用原纯净系统提供…

Flask学习(五):flask中添加装饰器

一、注意装饰器函数所在的位置&#xff1a; 代码示例如下&#xff1a; from flask import Flaskapp Flask(__name__)def wapper(func):def inner(*args, **kwargs):print("执行了装饰器")return func(*args, **kwargs)return innerwapper app.route("/index1…

CTF题型 匿名函数考法例题总结

CTF题型 匿名函数考法&例题总结 文章目录 CTF题型 匿名函数考法&例题总结一 .原理分析二 .重点匿名函数利用1.create_function()如何实现create_function代码注入 2.array_map()3.call_user_func()4.call_user_func_array()5.array_filter() 三.例题讲解1.[Polar 靶场 …

【WEB3安全基建项目Secwarex】空投指南

GoPlusSecurity是WEB3安全基建项目&#xff0c;3月8日完成400万美元的私募融资&#xff0c;目前总融资已经高达1500万美元&#xff0c;其中包括Binance Labs、Huobi Incubator、Kucoin Ventures、Avalanche等知名机构参投。 1、打开网址&#xff1a;secwarex.io&#xff0c;点…

【考研数学】武忠祥全年各阶段用书搭配

正常来说&#xff0c;你已经跟了武忠祥老师&#xff0c;那武老师的高数辅导讲义和严选题&#xff0c;应该你都有入手了&#xff0c;这个时候你再加一本1800&#xff0c;如何能够保证有充分的时间&#xff0c;将这些习题册做透&#xff0c;将它们的最大作用发挥出来呢&#xff0…

【C++】仿函数优先级队列反向迭代器

目录 一、优先级队列 1、priority_queue 的介绍 2、priority_queue 的使用 3、 priority_queue 的模拟实现 1&#xff09;priority_queue()/priority_queue(first, last) 2&#xff09;push&#xff08;x&#xff09; 3&#xff09;pop&#xff08;&#xff09; 4&#…

Vue+Element-UI Table表格实现复选框单选效果(隐藏表头上的全选Checkbox)

实现效果 完整代码 <div class"box-pos"><el-table ref"table" :header-cell-style"{ color: #FFF, background: #333 }":cell-style"{ color: #FFF, background: #333 }" :data"grListData" style"width: 1…

前端知识点03(JS)

文章目录 前端知识点03&#xff08;JS&#xff09;1、JS中this指向问题2、script中的async和defer的区别3、setTimeOut和setInterval4、Es6和ES5的区别5、ES6的新特性 &#x1f389;写在最后 前端知识点03&#xff08;JS&#xff09; hello hello~ &#xff0c;这里是 code袁~&…