SQLiteC/C++接口详细介绍之sqlite3类(五)
快速跳转文章列表:SQLite—系列文章目录
上一篇:SQLiteC/C++接口详细介绍之sqlite3类(四)
下一篇:SQLiteC/C++接口详细介绍之sqlite3类(六)(未发表)
14.sqlite3_busy_handler函数:
用于在访问共享数据库时处理数据库锁定,并如果某个共享数据库已经处于锁定状态,则可以排队查询等待一段时间,或在达到最大等待时限时放弃等待查询,从而避免资源浪费和死锁问题。
函数的原型:
int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
其中第一个参数是要操作的数据库句柄,第二个参数是一个函数指针,用于在数据库被锁时进行回调,第三个参数是传递给回调函数的上下文参数。
回调函数需要返回一个值,以确定是否继续等待或放弃查询等待,如果返回0,则一直等待,如果返回非零值,则直接中断查询。
注意:sqlite3_busy_handler函数不能在事务过程中使用,否则会影响数据库会话的一致性和完整性。因此,在使用此函数之前,应先检查当前是否存在任何激活的事务,并在必要时回滚事务,以免引起意外的数据库文件损坏。
例如:
1. 定义回调函数:为了使用sqlite3_busy_handler(),需要先定义一个回调函数。该函数有两个参数,即被占用的数据库对象和被占用次数。如果该函数返回0,则表示可以继续尝试访问该对象;如果返回非0值,则表示等待指定时间后再次尝试访问。
static int callback(void *data, int count) {int delay = 1000;printf("Database is busy, waiting %d ms...\n", delay);usleep(delay * 1000);return 1;}
在上面的代码中,我们定义了一个名为callback()的回调函数,当访问数据库时发生"Busy"错误时,该函数将等待1秒后再次尝试访问。如果该回调函数返回1,则下次访问将再次询问该回调函数。
2. 注册回调函数:在使用sqlite3_open()打开数据库时,可以使用sqlite3_busy_handler()函数注册上面定义的回调函数。
sqlite3 *db;int rc = sqlite3_open("mydb.db", &db);if (rc == SQLITE_OK) {sqlite3_busy_handler(db, callback, NULL);// ...}
在上面的代码中,我们在打开名为mydb.db的数据库时,使用了sqlite3_busy_handler()函数注册了callback()回调函数。
在使用sqlite3_busy_handler()处理"Busy"错误时,需要注意一些问题:
- 该函数注册的回调函数只有在执行一些特定的SQL语句时才会被调用,例如UPDATE、INSERT、DELETE等更新操作。
- 回调函数需要注意自旋锁问题(spin-lock),以防止死循环和线程或进程卡死。
- 注册回调函数可能会影响数据库的性能,因此需要根据具体情况进行测试和调整。
在多个线程或者进程并发访问SQLite数据库时,使用sqlite3_busy_handler()函数可以有效地避免"Busy"错误,并提高程序的可靠性和稳定性。
15.sqlite3_db_name函数
在多数据库连接的情况下用于获取给定数据库连接或游标所关联的数据库的名称。这个函数可以用于跟踪数据库文件的来源及管理,特别是在使用动态绑定的SQL语句时。
函数的原型:
const char *sqlite3_db_name(sqlite3 *db, const char *zDbName);
const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
其中db参数是一个指向SQLite数据库连接对象的指针,zDbName参数是一个指向包含所需数据库名称的字符数组的指针。如果第二个参数不为NULL,则该函数将获取指定列,否则默认获取主数据库连接或游标所关联的数据库名称。
函数返回值是一个指向包含数据库名称的空终止字符串的指针。如果指定的数据库不存在,则返回NULL。
注意:sqlite3_db_name函数只能在一个已打开的数据库连接上使用,并且仅能返回当前打开的数据库的名称,不能获取SQLite中所有数据库的名称。如果需要获取所有数据库的名称,则需要执行SQLite系统表查询或系统函数调用。
例如:
下面是sqlite3_db_name()的使用方法:
获取数据库名称:使用sqlite3_db_name()函数获取该连接对象关联的数据库名称。
const char *db_name = sqlite3_db_name(db, 0);printf("Database name: %s\n", db_name);
在上面的代码中,我们使用sqlite3_db_name()函数获取与db连接相关联的数据库的名称,并将其打印出来。
注意:如果一个数据库连接关联多个数据库,比如通过ATTACH命令关联多个数据库时,sqlite3_db_name()函数将返回最近一次执行的SQL语句中指定的数据库名称。如果没有指定数据库名称,则返回NULL。
16.sqlite3_busy_timeout函数
设置在多用户或多线程并发访问文件时等待其它连接锁释放的最大时间。当某个连接在对资源进行访问时,如果资源已被另一个连接锁定,则该连接将等待指定的时间,直到资源被释放或达到指定的最大等待时间为止。
函数的原型:
int sqlite3_busy_timeout(sqlite3*, int ms);
其中ms参数表示等待的毫秒数,如果为非正数,则取消忙等待并释放连接锁。函数的返回值表示是否设置成功,如果返回SQLITE_OK,则表示设置成功,否则返回相应的错误码。
注意:sqlite3_busy_timeout函数必须在连接之前进行调用,否则设置将不起作用。此外,在使用此函数时应注意避免死锁问题,例如设置一个合适的等待时间,并在必要时使用函数进行回调,以避免长时间等待导致资源浪费和死锁问题。
1. 设置"busy"超时:使用sqlite3_busy_timeout()函数设置在访问数据库时发生"Busy"错误时等待的时间,单位为毫秒。
sqlite3_busy_timeout(db, 5000);
在上面的代码中,我们设置等待时间为5000毫秒,即5秒。
2. 访问数据库:在设置"busy"超时后,可以开始访问数据库。
int result = sqlite3_exec(db, "SELECT * FROM mytable", callback, 0, &zErrMsg);if (result != SQLITE_OK) {fprintf(stderr, "SQL error: %s\n", zErrMsg);sqlite3_free(zErrMsg);}
在上面的代码中,db是我们打开数据的对象我们使用sqlite3_exec()函数执行SQL语句并处理结果。
注意:
sqlite3_busy_timeout()只对在访问数据库时发生的"Busy"错误起作用。如果程序占用数据库长时间不释放,造成阻塞,这时sqlite3_busy_timeout()就不起作用了。在实际使用中,应该在编写程序时避免出现长时间占用数据库的情况。
17.sqlite3_db_readonly函数用于判断指定的数据库连接或游标是否处于只读模式。
函数的原型:
int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
其中,参数db是一个指向SQLite数据库连接对象的指针,参数zDbName是一个指向包含所需数据库名称的字符数组的指针。如果第二个参数不为NULL,则该函数将获取指定列,否则默认获取主数据库连接或游标所关联的数据库。
函数返回值是一个整数,表示指定数据库是否处于只读模式。返回值为1时表示该数据库处于只读模式,返回值为0表示该数据库可以进行读写操作。
注意:此函数只能用于已经打开的数据库连接或游标。
例如:
判断数据库是否为只读:使用sqlite3_db_readonly()函数判断数据库是否为只读。
int is_readonly = sqlite3_db_readonly(db, "main");
if (is_readonly == 1) {printf("The database is readonly\n");} else {printf("The database is not readonly\n");}
代码中,db是数据库连接对象,使用sqlite3_db_readonly()函数判断与db对象相关联的名为main的数据库是否为只读。如果该数据库只读,则打印"The database is readonly",否则打印"The database is not readonly"。
注意:sqlite3_db_readonly()函数的第二个参数指定要查询的数据库名称。如果没有指定任何数据库名称,则默认查询"main"数据库。如果指定的数据库不存在,则返回-1。
18.sqlite3_last_insert_rowid
函数用于获取最近插入数据的行ID 。
函数的原型:
sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
函数返回一个sqlite_int64类型的值,表示最近一次插入数据的行ID。如果还未插入数据,则返回0。
例如:
在SQLite中,当表定义了一个自增长的主键字段时,插入一条新记录时,该字段将自动生成一个独一无二的值,我们可以使用sqlite3_last_insert_rowid()函数获取该值。
下面是sqlite3_last_insert_rowid()的使用方法:
1. 执行插入操作:使用SQL语句执行一条INSERT操作,在执行插入操作时,必须包含自增长的主键列。
sqlite3 *db;int rc = sqlite3_open("mydb.db", &db);if (rc == SQLITE_OK) {char *sql = "INSERT INTO mytable (name, age) VALUES ('Tom', 25)";rc = sqlite3_exec(db, sql, NULL, NULL, NULL);if (rc != SQLITE_OK) {printf("Error: %s\n", sqlite3_errmsg(db));} }
在上面的代码中,我们使用sqlite3_exec()函数执行一条INSERT语句,插入一条记录到名为mytable的表中。
2. 获取主键值:使用sqlite3_last_insert_rowid()函数获取自动生成的主键值。
sqlite3_int64 last_rowid = sqlite3_last_insert_rowid(db);
printf("Last insert rowid: %lld\n", last_rowid);
代码中,我们使用sqlite3_last_insert_rowid()函数获取刚插入记录的主键值,并将其打印出来。
注意:该函数只能用于最近执行的INSERT或REPLACE命令之后,否则将返回不可预测的结果。该函数不需要连接句柄或游标对象进行调用,只需要在执行INSERT或REPLACE命令之后立即调用即可。sqlite3_last_insert_rowid()函数获取自动生成的主键值只针对自增长的主键列有效,并且只能获取最近插入的记录的主键值。如果不存在自增长的主键列或者没有执行任何插入操作,则该函数返回0。
相关文章:

SQLiteC/C++接口详细介绍之sqlite3类(五)
快速跳转文章列表:SQLite—系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(四) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(六)(未发表) 14.sqlite3_busy_handle…...

Linux 之二:CentOS7 的 IP 常用命令和配置及 xshell 基本使用方法
1. 进入虚拟机 点击右键---进入终端--输入 ip adrr 或 ifconfig 查看ip地址 下面输入命令 ifconfig(注意:不是 ipconfig ) 或 ip addr 来查看当前系统 IP 查看到IP 后,比如:上面是 192.168.184.137 1.1 IP 常用命令…...

24-Java策略模式 ( Strategy Pattern )
Java策略模式 摘要实现范例 策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。 策略模式属于行为型模式 摘要 1. 意图 针对一组算法,将每一个算法封装到具有共…...
突破编程_C++_C++11新特性(模板的改进与细节)
1 模板右尖括号的改进 在 C11 之前,模板的解析和实例化过程中,右尖括号 > 的处理有时会导致一些意外的结果,特别是在嵌套模板或模板模板参数中。这是因为 C 编译器通常会试图“查看前方”来确定何时结束模板参数的列表,这有时…...

云原生消息流系统 Apache RocketMQ 在腾讯云的大规模生产实践
导语 随着云计算技术的日益成熟,云原生应用已逐渐成为企业数字化转型的核心驱动力。在这一大背景下,高效、稳定、可扩展的消息流系统显得尤为重要。腾讯云高级开发工程师李伟先生,凭借其深厚的技术功底和丰富的实战经验,为我们带…...
Node.js的事件驱动模型(非阻塞I/O)
Node.js的事件驱动模型是它能高效处理并发的关键。这个模型允许Node.js在单个线程上运行,同时通过非阻塞I/O操作来处理成千上万的并发连接。下面是对Node.js事件驱动模型的详细解释: 事件循环(Event Loop) 事件循环是Node.js事件…...

java过滤器Filter相关知识点汇总
1.Filter概述 Servlet Filter又称Servlet过滤器,它是在Servlet2.3规范中定义的,能够对Servlet容器传给Web资源的request对象和response对象执行检查和修改。 Filter不是Servlet,不能直接访问,其本身也不能生成request对象和resp…...

旅游景区公共广播 园区广播 公路服务区广播
旅游景区公共广播 园区广播 公路服务区广播 旅游景区公共广播 旅游景区公共广播(又称背景音乐)简称BGM,它的主要作用是掩盖噪声并创造一种轻松和谐的气氛,是一种创造轻松愉快环境气氛的音乐。掩盖环境噪声,创造与旅游景区相适应的气氛&#…...

Elastic Stack--09--ElasticsearchRestTemplate
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 spring-data-elasticsearch提供的APIQueryBuildersElasticsearchRestTemplate 方法ElasticsearchRestTemplate ---操作索引 ElasticsearchRestTemplate ---文档操作…...

论坛管理系统|基于Spring Boot+ Mysql+Java+B/S架构的论坛管理系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)
推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 目录 前台功能效果图 管理员功能登录前台功能效果图 用户功能模块 系统功能设计 数据库E-R图设计 l…...
2022 Task 2 Max Sum of 2 integers sharing first and last digits
Task 2 There is an array A consisting of N integers. What’s the maximum sum of two integers from A that share their first and last digits? For example, 1007 and 167 share their first(1) and last(7) digits, whereas 2002 and 55 do not. Write a function: …...
【分布式websocket】聊天系统消息加密如何做
前言 先介绍一下对称加密算法,在介绍一下加密流程,然后是介绍一下查询加密消息的策略。然后结合现有技术架构然后去选型。 决定采用客户端解密。简而言之就是采用对称服务端加密。然后将加密内容存储到消息表的content字段。然后客户拉取content字段 然…...

网络建设与运维培训介绍和能力介绍
1.开过的发票 3.培训获奖的证书 4合同签署 5.实训设备...
3 种方法限制 K8s Pod 磁盘容量使用
容器在运行期间会产生临时文件、日志。如果没有任何配额机制,则某些容器可能很快将磁盘写满,影响宿主机内核和所有应用。 容器的临时存储,例如 emptyDir,位于目录/var/lib/kubelet/pods 下: /var/lib/kubelet/pods/ …...

05-ESP32-S3-IDF USART
ESP32-S3 IDF USART详解 USART简介 USART是一种串行通信协议,广泛应用于微控制器和计算机之间的通信。USART支持异步和同步模式,因此它可以在没有时钟信号的情况下(异步模式)或有时钟信号的情况下(同步模式ÿ…...
安塔利斯升级php8
1、includes/classes/class.Database.php 255行 multi_query方法加返回类型 :bool query方法加返回类型:: mysqli_result|bool 2、includes/classes/class.Session.php on line 91 Optional parameter $planetID declared before required parameter $dpath is…...

Clickhouse MergeTree 原理(一)
作者:俊达 MergeTree是Clickhouse里最核心的存储引擎。Clickhouse里有一系列以MergeTree为基础的引擎(见下图),理解了基础MergeTree,就能理解整个系列的MergeTree引擎的核心原理。 本文对MergeTree的基本原理进行介绍…...

【C语言】字符串函数上
👑个人主页:啊Q闻 🎇收录专栏:《C语言》 🎉道阻且长,行则将至 前言 这篇博客是字符串函数上篇,主要是关于长度不受限制的字符串函数(strlen,strcpy,strcat,strcm…...

Java集合基础知识总结(绝对经典)
List接口继承了Collection接口,定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。 实际上有两种list:一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的L…...

Linux:导出环境变量命令export
相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 Linux中的内建命令export命令用于创建一个环境变量,或将一个普通变量导出为环境变量,并且在这个过程中,可以给该环境变量赋值。 下面…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...