当前位置: 首页 > news >正文

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

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

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

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

​37.sqlite3_load_extension 

用于在SQLite3中加载外部C语言编写的动态链接库(DLL)。

在SQLite3中,外部C语言编写的动态链接库通常被称为扩展,扩展可以增强SQLite3的功能以匹配特定的应用程序需求。通过加载扩展,开发人员可以轻松地在SQLite3的核心功能之外添加自定义功能。

sqlite3_load_extension原型如下:

int sqlite3_load_extension(sqlite3 *db, const char *zFile, const char *zProc, char **pzErrMsg);

其中,sqlite3是指向SQLite3数据库实例的指针,zFile是指向包含扩展代码的动态链接库的文件路径的指针,zProc是指向要调用的函数的名称的指针,pzErrMsg用于存储错误消息的地址。

下面是一个简单的示例,展示如何使用sqlite3_load_extension函数加载在操作系统中位于路径“/path/to/extension.dll”的扩展库:

#include <sqlite3.h>
#include <stdio.h>
int main(int argc, char* argv[]) {sqlite3* db;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 = sqlite3_load_extension(db, "/path/to/extension.dll", NULL, NULL);if (rc != SQLITE_OK) {printf("Can't load extension: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭数据库sqlite3_close(db);return 0;
}

在上面的示例代码中,我们使用sqlite3_load_extension函数加载操作系统中位于路径“/path/to/extension.dll”的扩展库。如果加载操作成功,sqlite3_load_extension函数将返回SQLITE_OK,如果加载操作失败,将返回一个错误代码。第三个参数zProc在本示例中设置为NULL,表示默认使用动态链接库中名称为“sqlite3_extension_init”的函数(如果存在)。如果您知道您想调用的函数的名称,请相应地设置该值。

注意:

SQLite3默认情况下禁止加载外部扩展库,因为这可能会导致不安全的代码嵌入到SQLite3实例中。要启用外部库加载功能,必须在编译SQLite3库时启用宏SQLITE_ENABLE_LOAD_EXTENSION,或者在运行时,在执行sqlite3_open函数之后调用sqlite3_enable_load_extension函数。

因为加载不安全的外部库可能会导致严重的安全漏洞,因此使用sqlite3_load_extension函数时,应该特别小心确保提供的外部库是安全的。在实际使用中,开发人员通常使用非常信任的库,并且更倾向于使用内置的SQLite3功能来支持其应用程序的需求。

38.sqlite3_next_stmt

sqlite3_next_stmt是SQLite3 C API提供的一个函数,它用于使指定的SQLite3数据库连接返回下一个准备好的语句。

在SQLite3中,每个已提交的SQL语句都被准备为一个SQLite3语句,准备语句后,使用sqlite3_step函数来执行它。sqlite3_next_stmt函数可以使SQLite3连接返回由先前调用sqlite3_prepare_v2或sqlite3_prepare16_v2函数准备好但未执行的下一个语句。这在需要按顺序执行多个SQL语句的情况下非常有用。

sqlite3_next_stmt原型如下:

sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);

其中,sqlite3是指向SQLite3数据库实例的指针,pStmt是指向以前已准备好但未执行的SQLite3语句的指针。如果将pStmt设置为NULL,则sqlite3_next_stmt将返回连接上的第一个准备语句。

下面是一个简单的示例,展示如何使用sqlite3_next_stmt函数在SQLite3中按顺序执行多个SQL语句:

#include <sqlite3.h>
#include <stdio.h>
int main(int argc, char* argv[]) {sqlite3* db;sqlite3_stmt* stmt;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 = sqlite3_prepare_v2(db, "INSERT INTO my_tbl (col1, col2) VALUES (?, ?)", -1, &stmt, NULL);if (rc != SQLITE_OK) {printf("Can't prepare statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 绑定参数rc = sqlite3_bind_int(stmt, 1, 123);rc = sqlite3_bind_text(stmt, 2, "test", -1, SQLITE_STATIC);// 执行第一条语句rc = sqlite3_step(stmt);if (rc != SQLITE_DONE) {printf("Can't execute statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 获得下一条语句stmt = sqlite3_next_stmt(db, stmt);// 第二条语句rc = sqlite3_prepare_v2(db, "SELECT * FROM my_tbl WHERE col1=?", -1, &stmt, NULL);if (rc != SQLITE_OK) {printf("Can't prepare statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 绑定参数rc = sqlite3_bind_int(stmt, 1, 123);// 执行第二条语句rc = sqlite3_step(stmt);if (rc != SQLITE_ROW) {printf("Can't execute statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭语句sqlite3_finalize(stmt);// 关闭数据库sqlite3_close(db);return 0;
}

在上面的示例代码中,我们首先准备并执行第一条语句,然后使用sqlite3_next_stmt函数得到下一条语句,即第二条语句。我们再次准备并执行第二条SQL语句,然后关闭它。通过这种方式,我们可以轻松地在SQLite3中按顺序执行多个SQL语句。 

39.sqlite3_overload_function 

sqlite3_overload_function是SQLite3 C API提供的一个函数,它用于在自定义SQLite3聚合函数中为一个特定的函数名称注册多个实现。

在SQLite3中,聚合函数是一种特殊的函数类型,它允许您计算一组值的聚合值并返回结果。SQLite3提供了一些内置的聚合函数,如SUM、AVG、COUNT等等。除此之外,您还可以自己编写SQLite3聚合函数,以适应特定的应用程序需求。

sqlite3_overload_function函数允许您为一个特定的函数名称注册多个实现,每个实现接受不同的参数数量和类型,并根据函数名称和参数数量和类型来选择正确的函数实现。

sqlite3_overload_function原型如下:

int sqlite3_overload_function(sqlite3 *db, const char *zFuncName, int nArg, int eTextRep, void *pApp);

其中,sqlite3是指向SQLite3数据库实例的指针,zFuncName是您要为其注册多个实现的函数名称,nArg是该函数所接受的参数数量,eTextRep是标识该函数接受的文本编码方式的标志,pApp是指向自定义数据的指针,该数据将在聚合函数调用期间传递给函数。

注意:

SQLite3聚合函数必须按特定的C函数原型编写,并且必须为每个参数定义参数类型。QLite3支持多种不同的数据类型,包括整数、浮点数、日期、时间等等。SQLite3还支持多种不同的文本编码方式,如UTF-8、UTF-16BE、UTF-16LE等等。因此,在实现聚合函数时,需要注意选择正确的参数类型和文本编码方式。

下面是一个简单的示例,展示如何使用sqlite3_overload_function函数为特定名称的函数注册多个实现:

#include <sqlite3.h>
#include <stdio.h>
// 定义一个ADD聚合函数
static void add_step(sqlite3_context *ctx, int argc, sqlite3_value **argv) {int sum = sqlite3_value_int(ctx);if (argc >= 2 && sqlite3_value_type(argv[0]) == SQLITE_INTEGER && sqlite3_value_type(argv[1]) == SQLITE_INTEGER) {sum += sqlite3_value_int(argv[0]);sum += sqlite3_value_int(argv[1]);}sqlite3_result_int(ctx, sum);
}
// 注册聚合函数
int register_add_function(sqlite3 *db) {int rc;// 注册一元ADD函数rc = sqlite3_create_function(db, "ADD", 1, SQLITE_UTF8, NULL, NULL, add_step, NULL);if (rc != SQLITE_OK) {return rc;}// 注册二元ADD函数rc = sqlite3_overload_function(db, "ADD", 2, SQLITE_UTF8, NULL);if (rc != SQLITE_OK) {return rc;}return SQLITE_OK;
}
int main(int argc, char* argv[]) {sqlite3* db;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;}// 注册ADD函数rc = register_add_function(db);if (rc != SQLITE_OK) {printf("Can't register function: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 执行一元ADD函数rc = sqlite3_exec(db, "SELECT ADD(100)", NULL, NULL, NULL);if (rc != SQLITE_OK) {printf("Can't execute statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 执行二元ADD函数rc = sqlite3_exec(db, "SELECT ADD(100, 200)", NULL, NULL, NULL);if (rc != SQLITE_OK) {printf("Can't execute statement: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭数据库sqlite3_close(db);return 0;
}

在上面的示例代码中,我们首先定义了一个名为ADD的聚合函数(它可以接受一个或两个整数参数,计算它们的和并返回结果),然后使用sqlite3_create_function函数将其注册为一元函数。接着,我们使用sqlite3_overload_function函数为名为ADD的函数注册了一个二元函数实现,这个实现接收两个整数参数并最终返回它们的总和。​

相关文章:

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

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十一&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十三&#xff09; ​37.sqlite3_load_extension 用于在SQLit…...

linux系统--------------mysql数据库管理

目录 一、SQL语句 1.1SQL语言分类 1.2查看数据库信息 1.3登录到你想登录的库 1.4查看数据库中的表信息 1.5显示数据表的结构&#xff08;字段&#xff09; 1.5.1数据表的结构 1.5.2常用的数据类型: 二、关系型数据库的四种语言 2.1DDL&#xff1a;数据定义语言&am…...

网络——入门基础

目录 协议 网络协议 OSI七层模型 网络传输基本流程 网络传输流程图 局域网通信 数据包的封装和解包 广域网通信 网络地址管理 IP地址 MAC地址 协议 关于什么是局域网&#xff0c;什么是广域网&#xff0c;我这里就不过多赘述了&#xff0c;我们直接来谈一下什么…...

二、yocto 集成ros2(基于raspberrypi 4B)

yocto 集成ros2 yocto 集成ros21. 下载ros layer2. 编译集成ros3. 功能验证 yocto 集成ros2 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第二篇文章。 一、yocto 编译raspberrypi 4B并启动 本节我们将ros2机器人操作系统移植到我们的yocto系统里面。 1. 下载ros laye…...

html--bug

文章目录 html html <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>老师</title><style>body {background-color: #008000;margin: 0px;cursor: none;overflow: hidden;}</style></head><bod…...

Java基础学习笔记三

环境变量CLASSPATH classpath环境变量是隶属于java语言的&#xff0c;不是windows操作系统的&#xff0c;和PATH环境变量完全不同classpath环境变量是给classloader&#xff08;类加载器&#xff09;指路的java A 。执行后&#xff0c;先启动JVM&#xff0c; JVM启动classload…...

Linux快速入门,上手开发 01.学习路线

少时曾许凌云志&#xff0c;当取世间第一流 再见少年拉满弓&#xff0c;不惧岁月不飓风 —— 24.3.20 1.Linux的发展历史 2.VM虚拟机的Linux初体验 3.图形化页面设置系统——快速上手 4.命令行操作——向专业前进 5.核心操作命令——必知必会&#xff08;管理企业级权限/定位b…...

JSX return里面如何用if判断

在JSX中,由于不能直接使用传统的JavaScript ​​if​​ 语句,但可以通过条件渲染来实现类似的效果。以下是一些方法: 1. 三元运算符(Ternary Operator) 最简单的条件渲染方式是使用三元运算符: return (<div>{condition ? <ComponentIfTrue /> : <Com…...

Vulnhub靶机渗透:DC-7打靶记录

前言 自信自强&#xff0c;来自于不怕苦、不怕难的积淀。宝剑锋从磨砺出&#xff0c;梅花香自苦寒来&#xff1b;任何美好理想&#xff0c;都离不开筚路蓝缕、手胼足胝的艰苦奋斗&#xff01; 靶场介绍 DC-7是一个初中级的靶场&#xff0c;需要具备以下前置知识&#xff1a;…...

目标检测---IOU计算详细解读(IoU、GIoU、DIoU、CIoU、EIOU、Focal-EIOU、SIOU、WIOU)

常见IoU解读与代码实现 一、✒️IoU&#xff08;Intersection over Union&#xff09;1.1 &#x1f525;IoU原理☀️ 优点⚡️缺点 1.2 &#x1f525;IoU计算1.3 &#x1f4cc;IoU代码实现 二、✒️GIoU&#xff08;Generalized IoU&#xff09;2.1 GIoU原理☀️优点⚡️缺点 2…...

探索并发编程:深入理解线程池

文章目录 前言一、线程池是什么&#xff1f;二、如何创建线程池1.使用Executors类2.使用ThreadPoolExecutor类手动配置线程池 总结 前言 随着计算机系统的不断发展和进步&#xff0c;我们需要处理更多的并发任务和复杂的操作。而线程池作为一种高效的线程管理机制&#xff0c;…...

html5cssjs代码 023 公制计量单位进位与换算表

html5&css&js代码 023 公制计量单位进位与换算表 一、代码二、解释 这段HTML代码定义了一个网页&#xff0c;用于展示公制计量单位的进位与换算表。 一、代码 <!DOCTYPE html> <html lang"zh-cn"> <head><meta charset"utf-8&quo…...

UE5.3 StateTree使用实践

近期浏览UE的CitySample&#xff08;黑客帝国Demo&#xff09;&#xff0c;发现有不少逻辑用到了StateTree学习一下&#xff0c;StateTree是多层状态机实现&#xff0c;以组件的形式直接挂载在蓝图中运行。 与平时常见的一些FSM库不同&#xff0c;StateTree并不会返回给外界当…...

【09】进阶JavaScript事件循环Promise

一、事件循环 浏览器的进程模型 何为进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 何为线程? 有了进程后,就可以运行程序的代码了。 运行代码的「人」称之…...

蓝桥备赛----基本语法总结

文章目录 输入输出知识点总结 输入 单个 #单个输入n input() #无参数 默认返回字符串n input("有提示参数的输入") #有提示性输入语句的输入&#xff0c;仍是以str类型返回n int(input()) #根据给定的类型输入&#xff0c;返回值类型intn float(input()) #根据…...

基于 Echarts + Python Flask ,我搭建了一个动态实时大屏监管系统

一、效果展示 1. 动态实时更新数据效果图 2. 鼠标右键切换主题 二、确定需求方案 支持Windows、Linux、Mac等各种主流操作系统&#xff1b;支持主流浏览器Chrome&#xff0c;Microsoft Edge&#xff0c;360等&#xff1b;服务器采用python语言编写&#xff0c;配置好python环…...

针对教育行业的网络安全方案有哪些

智慧校园”是教育信息化进入高级阶段的表现形式&#xff0c;比“数字校园”更先进。集体知识共融、共生、业务应用融合创新、移动互联网物联网高速泛在是其重要特征。特别是在互联网教育的大环境下&#xff0c;为了更好的发挥智慧化教学服务和智慧化教学管理功能&#xff0c;需…...

C++ 编程入门指南:深入了解 C++ 语言及其应用领域

C 简介 什么是 C&#xff1f; C 是一种跨平台的编程语言&#xff0c;可用于创建高性能应用程序。 C 是由 Bjarne Stroustrup 开发的&#xff0c;作为 C 语言的扩展。 C 为程序员提供了对系统资源和内存的高级控制。 该语言在 2011 年、2014 年、2017 年和 2020 年进行了 4…...

latex变量上下加自适应长度箭头

latex变量上下加自适应长度箭头 在变量上加箭头的代码如下 % 在上 \overrightarrow{A B} \overleftarrow{A B} % 在下 \underrightarrow{A B} \underleftarrow{A B}得出的结果依次如下 A B → , A B ← , A B → , A B ← \overrightarrow{A B},\overleftarrow{A B}, \under…...

鸿蒙4.0ArkUI快速入门(一)应用模型

ArkUI篇 应用模型Stage模型FA模型模型对比 应用模型 应用模型是HarmonyOS为开发者提供的应用程序所需能力的抽象提炼&#xff0c;它提供了应用程序必备的组件和运行机制。 HarmonyOS先后提供了两种应用模型&#xff1a; FA&#xff08;Feature Ability&#xff09;模型&…...

51单片机入门实战:用独立按键控制数码管显示0~9(附Proteus仿真文件)

51单片机实战&#xff1a;独立按键与数码管交互全流程解析 第一次接触51单片机时&#xff0c;看着那些闪烁的LED和跳动的数字&#xff0c;总有种打开新世界大门的兴奋感。记得我最初尝试用按键控制数码管显示时&#xff0c;按键抖动问题让我调试到凌晨三点——这段经历让我深刻…...

基于路阻信息的电动汽车充电需求分布 路网-电网耦合、排队论、温度耗电量、配电网潮流,通过时序蒙...

基于路阻信息的电动汽车充电需求分布 路网-电网耦合、排队论、温度耗电量、配电网潮流&#xff0c;通过时序蒙塔卡洛模拟&#xff0c;考虑路阻信息、温度、排队论时间&#xff0c;去除规模影响&#xff0c;配有相关文献。车-电-路网一体化负荷预测系统&#xff1a;多模态蒙特卡…...

从零到一:构建支持FCM推送的Android应用实战指南

1. 为什么需要FCM推送&#xff1f; 移动应用推送功能就像餐厅的叫号系统——没有它&#xff0c;用户就不知道自己的"菜品"&#xff08;新消息/内容&#xff09;是否已经准备好。FCM&#xff08;Firebase Cloud Messaging&#xff09;作为Google官方推荐的推送解决方…...

STM32 SPI模式SD卡驱动开发与FAT16文件系统实现

1. 项目概述&#xff1a;基于STM32的SD卡SPI协议库开发作为一名长期从事嵌入式开发的工程师&#xff0c;我最近完成了一个针对STM32平台的SD卡SPI协议库实现。这个项目的核心目标是构建一个严格遵循SD协议标准的轻量级库&#xff0c;特别适合资源受限的嵌入式环境。与常见的Ard…...

世界模型:AI理解现实的新范式与AGI的关键路径

摘要 世界模型是一种能够对现实世界环境进行仿真,并基于文本、图像、视频及运动等多模态输入生成视频、预测未来状态的生成式人工智能模型。它解决了传统大模型"只懂语言、不懂物理、只会生成、不会推演"的幻觉与落地瓶颈,被认为是实现通用人工智能(AGI)的必经之路…...

Obsidian知识管理模板:告别信息碎片化,构建你的第二大脑

Obsidian知识管理模板&#xff1a;告别信息碎片化&#xff0c;构建你的第二大脑 【免费下载链接】obsidian-template Starter templates for Obsidian 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-template 你是否经常感到信息过载&#xff1f;收藏的文章从未…...

【ArcGIS Pro二次开发】:三调地类面积精准统计与数据清洗实战

1. 三调地类面积统计的业务痛点 做国土调查数据处理的朋友都知道&#xff0c;三调数据最让人头疼的就是地类名称不规范。我去年接手一个省级三调项目时&#xff0c;光是清理"养殖坑塘"这类非标准表述就花了整整两周。不同作业单位提交的数据里&#xff0c;光是坑塘水…...

用动态规划思路,一步一步实现响应式数据(从本质到落地)

用动态规划思路&#xff0c;一步一步实现响应式数据&#xff08;从本质到落地&#xff09; 文章目录用动态规划思路&#xff0c;一步一步实现响应式数据&#xff08;从本质到落地&#xff09;一、第一步&#xff1a;用动态规划逆向思维&#xff0c;拆解响应式的“最终目标”1. …...

从自动售货机到芯片验证:手把手拆解BDD如何把指数级问题‘压扁’

从自动售货机到芯片验证&#xff1a;BDD如何将指数级问题"压扁"的魔法 当你站在一台老式自动售货机前&#xff0c;投入硬币组合时&#xff0c;是否想过这简单的机械动作背后隐藏着芯片验证领域的革命性算法&#xff1f;35美分的自动售货机验证问题&#xff0c;恰如芯…...

突破ThinkPad散热极限:TPFanCtrl2双风扇控制终极指南

突破ThinkPad散热极限&#xff1a;TPFanCtrl2双风扇控制终极指南 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 还在为ThinkPad风扇噪音过大或散热不足而烦恼吗&#…...