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://www.mzph.cn/news/750036.shtml

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

相关文章

深入探讨医保购药APP的技术架构与设计思路

随着移动互联网的发展&#xff0c;医疗保健行业也迎来了数字化转型的浪潮。医保购药APP作为医保体系数字化的一部分&#xff0c;其技术架构和设计思路至关重要。接下来&#xff0c;小编将为您讲解医保购药APP的技术架构与设计思路&#xff0c;为相关从业者提供参考和启发。 一、…

【知识简略】 简单理解SpringCloud微服务架构:服务注册发现、配置中心、限流、熔断、降级、网关路由等

主要介绍Nacos那一套。 目录 微服务架构1.服务注册发现2.配置中心3.限流、熔断、降级4.网关路由 微服务架构 Spring Cloud 微服务架构中&#xff0c;Nacos 提供了一系列核心组件和服务治理功能&#xff0c;以下是对 Nacos 中涉及的相关组件及其功能的详细解释&#xff1a; 1.…

51单片机基础篇系列-定时/计数器的控制工作方式

&#x1f308;个人主页&#xff1a;会编程的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” 定时/计数器的控制 80C51单片机定时/计数器的工作由两个特殊功能寄存器控制&#xff0c;TMOD用于设置其工作方式&#xff1a; 1.工作方式寄存器TMOD 工作方式寄存器TMO…

Rust学习02:推荐一本入门书,免费的

都说Rust的学习曲线很陡峭&#xff0c;试过才知雀实不容易。 先说我的基础&#xff0c;非科班&#xff0c;自学Python&#xff0c;写过几个小程序。 我买书从来不扣扣嗖嗖的&#xff0c;所以先啃了几本Rust的入门书&#xff0c;包括&#xff1a; Tim McNamara的《Rust实战》&am…

inux(CentOS)/Windows-C++ 云备份项目(项目文件操作工具类设计,完成项目基本文件操作-读写-压缩-目录操作)

文章目录 1. 项目文件操作工具类设计 1. 项目文件操作工具类设计 根据前面的分析&#xff0c;这个文件类的基本属性如下&#xff1a; 文件大小信息文件最后修改时间文件最后一次访问时间&#xff0c;方便文件的热点管理文件名称&#xff0c;需要从http 请求行上的uri中获取基…

P8780 [蓝桥杯 2022 省 B] 刷题统计 Python

[蓝桥杯 2022 省 B] 刷题统计 题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a a a 道题目&#xff0c;周六和周日每天做 b b b 道题目。请你帮小明计算&#xff0c;按照计划他将在第几天实现做题数大于等于 n n n 题? 输入格式 输入一…

JavaWeb(p135-p155)

分页查询 可以利用分页插件PageHelper 1.引入依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.2</version> </dependency>2.EmpMapper …

Python 数据结构与算法

Python 是一种强大且灵活的编程语言&#xff0c;非常适合用于实现各种数据结构和算法。数据结构和算法是计算机科学中的基础概念&#xff0c;对于解决实际问题、优化程序性能以及提高代码的可读性和可维护性至关重要。 ### 数据结构 数据结构是计算机存储、组织和管理数据的方…

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

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

一起学数据分析_3(模型建立与评估_2)

为什么要评估? 在进行数据分析时&#xff0c;尤其是在使用像sklearn这样的机器学习库建立模型后&#xff0c;模型评估的重要性不言而喻。模型评估不仅是对模型性能的一次全面检验&#xff0c;更是确保模型在实际应用中能够达到预期效果的关键步骤。 首先&#xff0c;模型评估…

iguana 库 C++ 反射原理

iguana Github : https://github.com/fananchong/iguana 官方介绍&#xff1a; universal serialization engine 虽然官方介绍是通用的序列化引擎&#xff0c;但实际上目前只支持&#xff1a; jsonyamlxml 不过&#xff0c; C 结构体/类的反射部分是通用的 通过该库&…

Linux 自动备份 mysql 脚本

这个脚本会将数据库备份为一个SQL文件&#xff0c;并将其保存在指定的目录中。 #!/bin/bash# MySQL配置 DB_USER"your_mysql_username" DB_PASS"your_mysql_password" DB_NAME"your_database_name" DB_HOST"localhost"# 备份目录 BAC…

Spring核心方法:Refresh全解(WebMVC如何装配、关联)

Spring核心方法&#xff1a;Refresh全解(WebMVC如何装配、关联) 这里是一个表格&#xff0c;列出了Spring容器刷新过程中执行的方法以及它们的作用&#xff1a; 方法名称描述prepareRefresh()初始化一些属性和状态&#xff0c;例如启动时间戳、活动标志、环境变量等。obtainF…

HTML-DAY2

HTML-DAY2 表格标签 表格的主要作用 表格主要用于显示、展示数据&#xff0c;因为它可以让数据显示的非常的规整&#xff0c;可读性非常好。特别是后台展示数据的时候&#xff0c;能够熟练运用表格就显得很重要。一个清爽简约的表格能够把繁杂的数据表现得很有条理。 Pink老…

Python的Selenium库中的模块、类和异常的汇总

这些是 Selenium Python 库中的模块、类和异常&#xff0c;用于实现自动化 Web 浏览器测试和网页操作。以下是它们的简单解释&#xff1a;Python Module Index — Selenium 4.18.1 documentation 1. selenium.common.exceptions&#xff1a;包含了 Selenium 中可能出现的异常。…

一款比 K8S 更好用的编排工具——Nomod

今天给笔友们推荐一款最近发现的服务编排工具Nomad。综合感觉就是功能很强大&#xff0c;姿势很优雅&#xff0c;相比 K8S 更加轻量级&#xff0c;相比 Docker-Compose 能轻松支持分布式。 Nomad 能做什么&#xff1f; Nomad 采用统一的工作流程&#xff0c;既可以轻松部署和管…

python自动化之(django)(2)

1、创建应用 python manage.py startapp apitest 这里还是从上节开始也就是命令行在所谓的autotest目录下来输入 然后可以清楚的看到 多了一个文件夹 2、创建视图 在views中加入test函数&#xff08;所建应用下&#xff09; from django.http import HttpResponse def tes…

C/C++蓝桥杯之卡片问题

问题描述&#xff1a;小兰有很多数字卡片&#xff0c;每张卡片上都是数字0&#xff5e;9。 小兰&#xff0c;准备用这些卡片拼一些数。她想从1开始拼出正整数&#xff0c;每拼一个就保存起来&#xff0c;卡片就不能再用来拼其他数了。 小兰想知道自己能从1拼到多少。 例如&a…

在Swift中集成Socket.IO进行实时通信

在Swift中集成Socket.IO进行实时通信 实时通信是许多现代应用程序的重要组成部分&#xff0c;从聊天应用程序到协作平台。Socket.IO 是一个流行的库&#xff0c;用于在 Web 和移动应用程序中实现实时的双向通信。在本文中&#xff0c;我们将讨论如何使用 Socket.IO-Client-Swi…

Rust的所有权和生命周期机制的本质

目录 所有权机制生命周期机制Rust的堆和栈堆和栈内存分配方式内存管理方式内存分配速度内存大小限制 Rust的所有权和生命周期机制的本质是关于数据在堆和栈中的存储方式。这两个概念是为了解决内存管理和资源分配的问题。 所有权机制 所有权机制确保每个值都有唯一的所有者&a…