SQLiteC/C++接口详细介绍之sqlite3类(十三)

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

上一篇:SQLiteC/C++接口详细介绍之sqlite3类(十二)

下一篇:SQLiteC/C++接口详细介绍之sqlite3类(十四)(未发表)

40.sqlite3_preupdate_blobwrite

用于将预更新钩子中的列值更改为BLOB值。

SQLite3预更新钩子是一种特殊类型的回调函数,在执行INSERT、UPDATE、DELETE语句时触发,允许您查看更改之前和之后的列值,并且可以修改列值、阻止更改、执行额外的更新并执行其他自定义操作。

sqlite3_preupdate_blobwrite函数是预更新钩子的一种特殊类型,允许您将列值更改为BLOB值。这是在预更新钩子中更新大型二进制数据类型(例如图像或文件)时非常有用的情况。

以下是sqlite3_preupdate_blobwrite函数的声明:

void sqlite3_preupdate_blobwrite(sqlite3 *db, void *pAux, int iKey1, int iKey2, int iIdx, const void *pData, int nData);

其中,sqlite3是指向SQLite3数据库实例的指针,pAux是指向与预更新钩子相关联的自定义数据的指针,iKey1、iKey2和iIdx参数指定正在更新的行和列的索引。pData和nData参数指定要写入的BLOB数据以及数据的长度。

注意:

sqlite3_preupdate_blobwrite函数需要在预更新钩子中注册,使用sqlite3session_preupdate_hook函数将其注册到数据库会话中。

下面是一个简单的示例,展示如何使用sqlite3_preupdate_blobwrite函数在SQLite3中预更新BLOB列:

#include <sqlite3.h>
#include <stdio.h>
static int preupdate_callback(void *pCtx, sqlite3 *db, int opcode, char const *dbname, char const *tblname, sqlite3_int64 rowid) {if (opcode == SQLITE_UPDATE) {printf("PRE-UPDATE HOOK: table=%s, rowid=%lld\n", tblname, rowid);// 获取预更新钩子上下文sqlite3session *pSession = (sqlite3session *)pCtx;sqlite3_preupdate_data *pChanges = sqlite3session_changeset(pSession, db, tblname);while (pChanges) {if (pChanges->op == SQLITE_UPDATE && pChanges->pChanges->nCol > 0) {for (int i = 0; i < pChanges->pChanges->nCol; i++) {sqlite3_value *pVal = pChanges->pChanges->apNew[i];if (pVal && sqlite3_value_type(pVal) == SQLITE_BLOB) {printf("COLUMN '%s' WILL BE UPDATED TO BLOB\n", sqlite3_column_name(pChanges->pStmt, i));// 将列值更改为BLOBsqlite3_preupdate_blobwrite(db, NULL, pChanges->iKey1, pChanges->iKey2, i, sqlite3_value_blob(pVal), sqlite3_value_bytes(pVal));}}}pChanges = pChanges->pNext;}}return SQLITE_OK;
}
int main(int argc, char* argv[]) {sqlite3* db;sqlite3_session *pSession;int rc;// 打开数据库rc = sqlite3_open("test.db", &db);if (rc != SQLITE_OK) {printf("Can't open database: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 创建数据库会话rc = sqlite3session_create(db, "temp.session", &pSession);if (rc != SQLITE_OK) {printf("Can't create session: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 注册预更新钩子rc = sqlite3session_preupdate_hook(pSession, preupdate_callback, pSession);if (rc != SQLITE_OK) {printf("Can't register preupdate hook: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 执行UPDATE语句rc = sqlite3_exec(db, "UPDATE my_table SET my_blob_column=?", NULL, NULL, NULL);if (rc != SQLITE_OK) {printf("Can't execute statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭数据库和会话sqlite3session_delete(pSession);sqlite3_close(db);return 0;
}

在上面的示例代码中,我们首先定义了一个预更新钩子回调函数preupdate_callback。当SQLITE_UPDATE操作码被传递给钩子时,我们遍历所有正在更新的列,并将值为BLOB的列更改为新的BLOB值。在此过程中,我们使用sqlite3_preupdate_blobwrite函数将列值更改为新值,并打印一条调试消息以示成功。

接着,我们创建一个SQLite3会话并将预更新钩子注册到会话中。最后,我们执行一个UPDATE查询更新带有一个BLOB列的表的行。更改将被捕获并处理,然后将提交到数据库。

注意:

预更新钩子仅在SQLite3的session扩展模块中可用。如果尝试将预更新钩子用于普通的SQLite3会话,则可能会收到错误消息。

41.sqlite3_preupdate_count

sqlite3_preupdate_count是SQLite3 C API提供的一个函数,它用于获取当前预更新操作中的更改数量。

SQLite3预更新钩子是一种特殊类型的回调函数,在执行INSERT、UPDATE、DELETE语句时触发,允许您查看更改之前和之后的列值,并且可以修改列值、阻止更改、执行额外的更新并执行其他自定义操作。

sqlite3_preupdate_count函数允许您获取当前预更新操作中的更改数量,这对于在预更新钩子中执行特定操作时非常有用。例如,您可能需要查看更改的列是否满足特定的条件,如果不符合,则阻止更改并抛出错误。

以下是sqlite3_preupdate_count函数的声明:

int sqlite3_preupdate_count(sqlite3 *db);

其中,sqlite3是指向SQLite3数据库实例的指针。该函数返回当前预更新操作中更改的列数。

注意:sqlite3_preupdate_count函数必须在预更新钩子中调用。预更新钩子由sqlite3session_preupdate_hook函数注册,并在执行预更新操作时调用。

下面是一个简单的示例,展示如何在SQLite3预更新钩子中使用sqlite3_preupdate_count函数:

#include <sqlite3.h>
#include <stdio.h>
static int preupdate_callback(void *pCtx, sqlite3 *db, int opcode, char const *dbname, char const *tblname, sqlite3_int64 rowid) {if (opcode == SQLITE_UPDATE) {printf("PRE-UPDATE HOOK: table=%s, rowid=%lld\n", tblname, rowid);// 获取预更新操作中更改的列数int nChanges = sqlite3_preupdate_count(db);printf("NUMBER OF CHANGES: %d\n", nChanges);// 遍历预更新操作中的列for (int i = 0; i < nChanges; i++) {sqlite3_preupdate_data const *p = sqlite3_preupdate_data_get(db, i);if (p && p->op == SQLITE_UPDATE && sqlite3_column_type(p->pStmt, p->iNew) == SQLITE_INTEGER) {int newValue = sqlite3_column_int(p->pStmt, p->iNew);printf("COLUMN #%d WILL BE UPDATED TO %d\n", i, newValue);// 检查更改的列是否符合特定条件if (newValue < 0 || newValue > 100) {printf("INVALID VALUE FOR COLUMN #%d\n", i);// 阻止更改并抛出错误sqlite3_preupdate_rollback(db);printf("ROLLBACK PRE-UPDATE\n");return SQLITE_ERROR;}}}}return SQLITE_OK;
}
int main(int argc, char* argv[]) {sqlite3* db;sqlite3_session *pSession;int rc;// 打开数据库rc = sqlite3_open("test.db", &db);if (rc != SQLITE_OK) {printf("Can't open database: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 创建数据库会话rc = sqlite3session_create(db, "temp.session", &pSession);if (rc != SQLITE_OK) {printf("Can't create session: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 注册预更新钩子rc = sqlite3session_preupdate_hook(pSession, preupdate_callback, NULL);if (rc != SQLITE_OK) {printf("Can't register preupdate hook: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 执行UPDATE语句rc = sqlite3_exec(db, "UPDATE my_table SET my_column=my_column+1", NULL, NULL, NULL);if (rc != SQLITE_OK) {printf("Can't execute statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭数据库和会话sqlite3session_delete(pSession);sqlite3_close(db);return 0;
}

在上面的示例代码中,我们首先定义了一个预更新钩子回调函数preupdate_callback。当SQLITE_UPDATE操作码被传递给钩子时,我们使用sqlite3_preupdate_count函数获取当前预更新操作中的更改数量。然后,我们遍历所有更改的列并检查它们是否符合特定条件,如果不符合,则阻止更改并抛出错误。在此过程中,我们还使用sqlite3_preupdate_rollback函数阻止更改并恢复当前事务的其他更改。需

注意:

如果在预更新钩子中使用sqlite3_preupdate_rollback函数,则必须返回SQLITE_ERROR以指示错误。接着,我们创建一个SQLite3会话并将预更新钩子注册到会话中。最后,我们执行一个UPDATE查询,将带有一个整数列的表的行添加1。所有更改将被捕获并处理,然后将提交到数据库。预更新钩子仅在SQLite3的session扩展模块中可用。如果尝试将预更新钩子用于普通的SQLite3会话,则可能会收到错误消息。

42.sqlite3_preupdate_depth

用于获取当前预更新操作的嵌套深度。

SQLite3预更新钩子是一种特殊类型的回调函数,在执行INSERT、UPDATE、DELETE语句时触发,允许您查看更改之前和之后的列值,并且可以修改列值、阻止更改、执行额外的更新并执行其他自定义操作。

sqlite3_preupdate_depth函数允许您获取当前预更新操作中的嵌套深度,也就是当前预更新的预更新操作的数量。这对于在嵌套的预更新操作中执行特定操作时非常有用。例如,当更改发生时,您可能需要查找更改的列所依赖的其他列,这可能需要深入预更新操作树来查找列。

以下是sqlite3_preupdate_depth函数的声明:

int sqlite3_preupdate_depth(sqlite3 *db);

其中,sqlite3是指向SQLite3数据库实例的指针。该函数返回当前预更新操作的嵌套深度,如果没有嵌套操作,则返回0。

需要注意的是,sqlite3_preupdate_depth函数必须在预更新钩子中调用。预更新钩子由sqlite3session_preupdate_hook函数注册,并在执行预更新操作时调用。

下面是一个简单的示例,展示如何在SQLite3预更新钩子中使用sqlite3_preupdate_depth函数:

#include <sqlite3.h>
#include <stdio.h>
static int preupdate_callback(void *pCtx, sqlite3 *db, int opcode, char const *dbname, char const *tblname, sqlite3_int64 rowid) {if (opcode == SQLITE_UPDATE) {printf("PRE-UPDATE HOOK: table=%s, rowid=%lld\n", tblname, rowid);// 获取预更新操作的嵌套深度int depth = sqlite3_preupdate_depth(db);printf("PRE-UPDATE DEPTH: %d\n", depth);// 检查更改的列是否依赖于其他列sqlite3_preupdate_data const *p = sqlite3_preupdate_data_get(db, 0);if (depth > 0 && p->op == SQLITE_UPDATE && sqlite3_column_type(p->pStmt, p->iNew) == SQLITE_INTEGER) {int newValue = sqlite3_column_int(p->pStmt, p->iNew);printf("COLUMN WILL BE UPDATED TO %d\n", newValue);// 获取依赖列的值sqlite3_preupdate_data const *pDep = sqlite3_preupdate_data_get_parent(db, 0);if (pDep && pDep->op == SQLITE_UPDATE && sqlite3_column_type(pDep->pStmt, pDep->iNew) == SQLITE_INTEGER) {int depValue = sqlite3_column_int(pDep->pStmt, pDep->iNew);printf("COLUMN DEPENDS ON ANOTHER COLUMN WITH VALUE %d\n", depValue);}}}return SQLITE_OK;
}
int main(int argc, char* argv[]) {sqlite3* db;sqlite3_session *pSession;int rc;// 打开数据库rc = sqlite3_open("test.db", &db);if (rc != SQLITE_OK) {printf("Can't open database: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 创建数据库会话rc = sqlite3session_create(db, "temp.session", &pSession);if (rc != SQLITE_OK) {printf("Can't create session: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 注册预更新钩子rc = sqlite3session_preupdate_hook(pSession, preupdate_callback, NULL);if (rc != SQLITE_OK) {printf("Can't register preupdate hook: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 执行UPDATE语句rc = sqlite3_exec(db, "UPDATE my_table SET my_column=my_column+1", NULL, NULL, NULL);if (rc != SQLITE_OK) {printf("Can't execute statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭数据库和会话sqlite3session_delete(pSession);sqlite3_close(db);return 0;
}

在上面的示例代码中,我们首先定义了一个预更新钩子回调函数preupdate_callback。当SQLITE_UPDATE操作码被传递给钩子时,我们使用sqlite3_preupdate_depth函数获取当前预更新操作中的嵌套深度。然后,如果更改的列依赖于其他列,则我们获取依赖列的值并打印一条调试消息。

在此过程中,我们还使用sqlite3_preupdate_data_get_parent函数获取当前预更新操作的父级预更新操作。需要注意的是,只有在预更新操作嵌套时,该函数才返回非空值。

接着,我们创建一个SQLite3会话并将预更新钩子注册到会话中。最后,我们执行一个UPDATE查询,将带有一个整数列的表的行添加1。所有更改将被捕获并处理,然后将提交到数据库。

需要注意的是,预更新钩子仅在SQLite3的session扩展模块中可用。如果尝试将预更新钩子用于普通的SQLite3会话,则可能会收到错误消息。

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

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

相关文章

相机拍照与摄影学基础

1.相机拍照 相机可能形状和大小不同&#xff0c;但基本功能相同&#xff0c;包括快门速度、光圈和感光度&#xff0c;这些是摄影的通用概念。即使是一次性相机也是基于这三个理念工作的。不同类型相机在这三个概念上的唯一区别是你可以控制这些功能的程度。这三个参数被称为相…

HCIP—OSPF课后练习一

本实验模拟了一个企业网络场景&#xff0c;R1、R2、R3为公司总部网络的路由器&#xff0c;R4、R5分别为企业分支机构1和分支机构2的路由器&#xff0c;并且都采用双上行方式与企业总部相连。整个网络都运行OSPF协议&#xff0c;R1、R2、R3之间的链路位于区域0&#xff0c;R4与R…

计算机设计大赛 题目:基于大数据的用户画像分析系统 数据分析 开题

文章目录 1 前言2 用户画像分析概述2.1 用户画像构建的相关技术2.2 标签体系2.3 标签优先级 3 实站 - 百货商场用户画像描述与价值分析3.1 数据格式3.2 数据预处理3.3 会员年龄构成3.4 订单占比 消费画像3.5 季度偏好画像3.6 会员用户画像与特征3.6.1 构建会员用户业务特征标签…

波奇学Linux:线程安全和自选锁和读写锁

STL不是线程安全的 单例模式的线程安全 自选锁&#xff1a;当线程申请锁失败时&#xff0c;不是挂起&#xff0c;而是一直申请 挂起等待锁 &#xff1a;当线程申请锁失败时&#xff0c;把锁挂起 一般临界区时间短的适合自选锁&#xff0c;长的适合挂起等待锁

Linux系统——Session ID(负载均衡如何保持会话)

目录 一、实验环境搭建 二、部署Nginx代理服务器配置 三、部署后端真是服务器Tomcat配置 四、配置Tomcat的Session ID会话保持 五、测试 此次实验是Tomcat后端服务器如何做Session ID会话保持 一、实验环境搭建 [rootlocalhost ~]#systemctl stop firewalld [rootlocalho…

Qt QTableWidget 实现行选中及行悬浮高亮

表格整行的 selected、hover 高亮需求很常见&#xff0c;但使用 Qt 提供的开箱即用的方法根本无法实现这个需求&#xff08;至少在当前的时间节点是不行的&#xff09;&#xff1b;想要实现这个效果必须要费一点点力气&#xff0c;我们尽量选择较为简单的方法。 话不多说&…

“import ... =“ 只能在 TypeScript 文件中使用

当你遇到这个问题很苦恼。 可以按照以下解决办法 使用ctrlshiftP 修改"javascript.validate.enable": false

从大模型到Agentscope——分布式Multi-Agent应用开发与部署

目录 Why需要分布式 案例 多进程的分布书版本能快速提升速度 分布式的挑战 AgentScope分布式解决 方案 实现RPC Agent 基于Actor模式的并行调度缺点&#xff1a;需要Agent内部决定消息传递目标 被调用的Agent立即返回占位符placeholder to_dist: 开启自动将单机进行扩展…

android中单例模式为什么会引起内存泄漏?

单例模式使用不恰当会造成内存泄漏。因为单例的静态特性使得单例的生命周期和应用的生命周期一样长&#xff0c; 如果一个对象已经不需要使用了&#xff0c;但是单例对象还持有该对象的引用&#xff0c;那么这个对象就不能被正常回收&#xff0c;因此会导致内存泄漏。 举个例子…

<Linux> 线程的同步与互斥

目录 前言&#xff1a; 一、资源共享问题 &#xff08;一&#xff09;多线程并发访问 &#xff08;二&#xff09;临界资源与临界区 &#xff08;三&#xff09;“锁” 是什么 二、多线程抢票场景 &#xff08;一&#xff09;并发抢票 &#xff08;二&#xff09;并发访…

学习笔记--强化学习(1)

参考&#xff1a;https://blog.csdn.net/koulongxin123/article/details/122676149 1.什么是强化学习&#xff1f; (1)定义 基于环境的反馈而行动&#xff0c;通过不断与环境的交互、试错&#xff0c;最终完成特定目的或者使得整体行动收益最大化&#xff08;是一种通过与环境…

YOLOv9改进策略:注意力机制 | SimAM(无参Attention),效果秒杀CBAM、SE

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;SimAM是一种轻量级的自注意力机制&#xff0c;其网络结构与Transformer类似&#xff0c;但是在计算注意力权重时使用的是线性层而不是点积 yolov9-c-CoordAtt summary: 972 layers, 51024476 parameters, 510…

L4 级自动驾驶汽车发展综述

摘要:为了减小交通事故概率、降低运营成本、提高运营效率,实现安全、环保的出行,自动驾驶 技术的发展已成为大势所趋,而搭配有L4 级自动驾驶系统的车辆是将车辆驾驶全部交给系统。据此,介绍了自动驾驶汽车的主流技术解决方案;分析了国内外L4 级自动驾驶汽车的已发布车型、…

学点Java打小工_Day4_Homework

1 统计数字 1 int[] scores{0,0,1,2,3,5,4,5,2,8,7,6,9,5,4,8,3,1,0,2,4,8,7,9,5,2,1,2,3,9}; 求出上面数组中0-9分别出现的次数 &#xff08;双重for循环&#xff09; Testpublic void solveProblem1() {int[] scores {0,0,1,2,3,5,4,5,2,8,7,6,9,5,4,8,3,1,0,2,4,8,7,9,5,2,…

JavaWeb笔记 --- 三、MyBatis

三、MyBatis 概述 MyBatis是一个持久层框架&#xff0c;用于简化JDBC Mapper代理开发 在resources配置文件包中创建多级目录用 / MyBatis核心配置文件 enviroments&#xff1a;配置数据库连接环境信息。 可以配置多个enviroment&#xff0c;通过default属性切换不同的envir…

大衍数列-蓝桥杯?-Lua 中文代码解题第2题

大衍数列-蓝桥杯&#xff1f;-Lua 中文代码解题第2题 中国古代文献中&#xff0c;曾记载过“大衍数列”, 主要用于解释中国传统文化中的太极衍生原理。 它的前几项是&#xff1a;0、2、4、8、12、18、24、32、40、50 … 其规律是&#xff1a;对偶数项&#xff0c;是序号平方再除…

数据可视化-ECharts Html项目实战(1)

在之前的文章中&#xff0c;我们学习了如何安装Visual Studio Code并下载插件&#xff0c;想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 安装 Visual Studio…

MATLAB环境下基于稀疏方法的基线校正

以光谱信号为例进行说明&#xff0c;光谱信号中基线的存在会降低样品定性和定量分析的准确性&#xff0c;因此在光谱分析前对光谱进行基线校正具有重要意义。光谱数据在采集过程中易受温度、湿度等环境因素影响&#xff0c;发生基线偏移现象。该现象不仅会导致纯谱的谱峰发生形…

CSS3技巧38:3D 翻转数字效果

博主其它CSS3 3D的文章&#xff1a; CSS3干货4&#xff1a;CSS中3D运用_css 3d-CSDN博客 CSS3干货5&#xff1a;CSS中3D运用-2_中3d-2-CSDN博客 CSS3干货6&#xff1a;CSS中3D运用-3_css3d 使用-CSDN博客 最近工作上烦心的事情太多&#xff0c;只有周末才能让我冷静一下 cod…

AI毕业论文降重GPTS,避免AI检测,高效完成论文

视频演示 AI毕业论文降重GPTS&#xff0c;避免AI检测&#xff0c;高效完成论文&#xff01; 开发目的 “毕业论文降重”GPTS应用&#xff0c;作用为&#xff1a;重新表述学术论文&#xff0c;降低相似性评分&#xff0c;避免AI检测。 使用地址 地址&#xff1a;毕业论文降重…