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;为相关从业者提供参考和启发。 一、…

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中获取基…

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

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

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

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

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…

一款比 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…

基于CNN多阶段图像超分+去噪(超级简单版)

这是之前的一项工作&#xff0c;非常简单&#xff0c;简单的复现了两个算法&#xff0c;然后把它们串起来了。 可执行的程序链接&#xff1a;CSDN; Github 我们分成两部分进行讲解&#xff1a; 1. 图像去噪 1.1 基本思路 图像的去噪工作基于很普通的CNN去噪&#xff0c;效…

Swift 面试题及答案整理,最新面试题

Swift 中如何实现单例模式&#xff1f; 在Swift中&#xff0c;单例模式的实现通常采用静态属性和私有初始化方法来确保一个类仅有一个实例。具体做法是&#xff1a;定义一个静态属性来存储这个单例实例&#xff0c;然后将类的初始化方法设为私有&#xff0c;以阻止外部通过构造…

Ubuntu Desktop - gnome-calculator (计算器)

Ubuntu Desktop - gnome-calculator [计算器] 1. Ubuntu Software -> gnome-calculator -> Install -> Continue2. Search your computer -> Calculator -> Lock to LauncherReferences 1. Ubuntu Software -> gnome-calculator -> Install -> Continu…

STM32中MicroLIB的关闭为什么会导致卡死----解析

STM32MicroLIB 大家好我是 MHZ 。最近又开始往回捡单片机的知识了~ 之前大学的时候都没用过 STM 的 CubeMX&#xff0c;这会拿来用着感觉很方便啊~ 果然科技在进步&#xff01; 在开发使用 Keil 对 STM32 进行开发的时候在会有一个叫做 MicroLIB 的选项。 这个的具体原因我搜…

C语言 内存函数

目录 前言 一、memcpy()函数 二、memmove()函数 三、memset函数 四、memcmp()函数 总结 前言 在C语言中内存是我们用来存储数据的地址&#xff0c;今天我们来讲一下C语言中常用的内存函数。 一、memcpy()函数 memcpy()函数与我们之前讲的strcpy()函数类似&#xff0c;只…

Android FrameWork 学习路线

目录 前言 学习路线&#xff1a; 1.基础知识 2、AOSP 源码学习 3. AOSP 源码编译系统 4. Hal与硬件服务 5.基础组件 6. Binder 7. 系统启动过程分析 8. 应用层框架​编辑 9. 显示系统 10. Android 输入系统 11. 系统应用 前言 Android Framework 涉及的行业相当广…

Django 解决新建表删除后无法重新创建等问题

Django 解决新建表删除后无法重新创建等问题 问题发生描述处理办法首先删除了app对应目录migrations下除 __init__.py以外的所有文件:然后&#xff0c;删除migrations中关于你的app的同步数据数据库记录最后&#xff0c;重新执行迁移插入 问题发生描述 Django创建的表&#xf…

HCIP—OSPF课后练习一

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

uniapp 利用uni-list 和 uni-load-more 组件上拉加载列表

列表的加载动作&#xff0c;在移动端开发中随处可见&#xff0c;笔者也是经常用到。今天正好有空&#xff0c;做一个总结&#xff0c;方便以后使用。uniapp 利用uni-list 和 uni-load-more 组件上拉加载列表操作步骤如下&#xff1a;1、资料准备 1&#xff09;、uni-load-more…

JavaWeb--HTML

一&#xff1a;HTML简介 *HTML是一门语言&#xff0c;所有的网页都是用HTML这门语言编写出来的&#xff1b; *HTML&#xff1a;超文本标记语言&#xff1b; 超文本&#xff1a;超越了文本的限制&#xff0c;比普通文本更强大。除了文字信息&#xff0c;还能定义图片&#xff…

C#对ListBox控件中的数据进行的操作

目录 1.添加数据&#xff1a; 2.删除数据&#xff1a; 3.清空数据&#xff1a; 4.选择项&#xff1a; 5.排序&#xff1a; 6.获取选中的项&#xff1a; 7.获取ListBox中的所有项&#xff1a; 8.综合示例 C#中对ListBox控件中的数据进行的操作主要包括添加、删除、清空、…