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

news2025/1/8 10:47:14

   快速跳转文章列表: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。

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

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

相关文章

【STL】string各种函数的应用

1.string 基本赋值操作 string assign(string str,int n) string assign(string str,int pos,int n) 2.string存取字符操作 (at()) 注意:[ ]越界不会抛出异常,at越界会抛出异常 3.string拼接…

从零开始利用MATLAB进行FPGA设计(一):建立脉冲检测模型的Simulink模型1

文章灵感来源于MATLAB官方免费教程:HDL Coder Self-Guided Tutorial 考虑到MATLAB官网的英文看着慢,再加上视频讲解老印浓浓的咖喱味,我决定记录利用MATLAB&Simulink&SystemGenerator进行FPGA数字信号处理的学习过程。 在进行数字信…

vue学习笔记24-组件事件配合v-model使用

搜索时v-model绑定的search数据时时发生变化 watch侦听器时时监察变化&#xff0c;一旦数据发生变化 &#xff0c;就实时发送数据给父组件 子组件的完整代码&#xff1a; <template>搜索&#xff1a;<input type"text" v-model"search"> <…

如何把网站的http改成https?

想把网站从不安全的HTTP换成安全的HTTPS&#xff1f;来瞧瞧下面几步操作&#xff1a; 1.挑个SSL证书&#xff1a; - 根据你的网站情况&#xff08;比如就一个域名、多个域名还是啥域名都得管&#xff09;&#xff0c;找一款适合的SSL证书&#xff0c;有免费的DV&#xff08;验…

k8s-Istio服务网络 27

官网&#xff1a;https://istio.io/latest/zh/about/service-mesh/ Istio与k8s的区别 SpringCloud传统微服务结合k8s与Istio与k8s结合&#xff1a; Istio数据面&#xff1a;通过envoy以sidecar方式拦截svc的流量来进行治理。 Istio控制面&#xff1a;pilot list/watch APIserv…

【WSN覆盖优化】基于改进黏菌算法的无线传感器网络覆盖 WSN覆盖优化【Matlab代码#65】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】1. 改进SMA算法1.1 改进参数p1.2 混沌精英突变策略 2. WSN节点感知模型3. 部分代码展示4. 仿真结果展示5. 资源获取 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取…

TypeScript(五)交叉类型,联合类型,映射类型

交叉类型 交叉类型是将多个类型合并为一个类型。可以把现有的多种类型叠加到一起成为一种类型&#xff0c;它包含了所需的所有类型的特性。使用符号 & 表示。交叉类型 A & B 表示&#xff0c;任何一个新类型必须同时属于 A 和 B&#xff0c;才属于交叉类型 A & B …

数据库基础知识超详细解析~‍(进阶/复习版)

文章目录 前言一、数据库的操作1.登入数据库2.创建数据库3.显示当前数据库4.使用数据库5.删除数据库 二、常用数据类型三、数据库的约束1约束类型2NULL约束3UNIQUE:唯一约束4DEFAULT&#xff1a;默认值约束5 PRIMARY KEY&#xff1a;主键约束6 FOREIGN KEY&#xff1a;外键约束…

MyBatis-Plus学习记录

目录 MyBatis-Plus快速入门 简介 快速入门 MyBatis-Plus核心功能 基于Mapper接口 CRUD 对比mybatis和mybatis-plus&#xff1a; CRUD方法介绍&#xff1a; 基于Service接口 CRUD 对比Mapper接口CRUD区别&#xff1a; 为什么要加强service层&#xff1a; 使用方式 CR…

【CSS颜色】

本文章属于学习笔记&#xff0c;在https://www.freecodecamp.org/chinese/learn/2022/responsive-web-design/中练习 三、CSS颜色 1、有两种主要的颜色模型:电子设备中使用的加性RGB(红、绿、蓝)模型和印刷品中使用的减色CMYK(青色、品红、黄色、黑色)模型。 使用RGB模型。这…

Ypay源支付6.9无授权聚合免签系统可运营源码

YPay是一款专为个人站长设计的聚合免签系统&#xff0c;YPay基于高性能的ThinkPHP 6.1.2 Layui PearAdmin架构&#xff0c;提供了实时监控和管理的功能&#xff0c;让您随时随地掌握系统运营情况。 说明 Ypay源支付6.9无授权聚合免签系统可运营源码 已搭建测试无加密版本…

FastWiki v0.1.0发布!新增超多功能

FastWiki 发布 v0.1.0 https://github.com/239573049/fast-wiki/releases/tag/v0.1.0 更新日志 兼容OpenAI接口格式删除Blazor版本UI删除useEffect,解决可能存在问题的bug修复对话可以看到所有对话Merge branch ‘master’ of https://gitee.com/hejiale010426/fast-wiki更新…

14、设计模式之命令模式(Command)

一、什么是命令模式 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;又叫动作模式或事务模式。它将请求&#xff08;命令&#xff09;封装成对象&#xff0c;使得可以用不同的请求对客户端进行参数化&#xff0c;具体的请求可以在运行时更改…

蓝桥杯-粘木棍-DFS

题目 思路 --有n根木棍&#xff0c;需要将其粘成m根木棍&#xff0c;并求出最小差值&#xff0c;可以用DFS枚举出所有情况。粘之前有n根短木棍&#xff0c;粘之后有m根长木棍&#xff0c;那么让长木棍的初始长度设为0。外循环让所有的短木棍都参与粘&#xff0c;内循环让要粘的…

基于SpringBoot的“企业客户信息反馈平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“企业客户信息反馈平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 平台首页界面图 技术文档界面图 问题信息…

C# Onnx C2PNet 图像去雾 室外场景

目录 介绍 效果 模型信息 项目 代码 下载 C# Onnx C2PNet 图像去雾 室外场景 介绍 github地址&#xff1a;https://github.com/YuZheng9/C2PNet [CVPR 2023] Curricular Contrastive Regularization for Physics-aware Single Image Dehazing 效果 模型信息 Model P…

专升本 C语言笔记-03 变量的作用域

1.变量的概念 内存中有个存储区域,这个地方的数据可以在同一类型范围内不断变化通过变量名,可以访问这块内存区域,获取里面的值; 变量名的构成:数据类型 变量名 值 C语言中变量声明格式: 数据类型 变量名 值 2.变量的注意 2.1.全局变量: 定义在函数外部的叫全局变量…

SD-WAN技术如何保障网络的持续连接和稳定性

在当今数字化时代&#xff0c;企业对于网络的稳定性和持续连接性需求日益增加。SD-WAN作为一种新兴的网络解决方案&#xff0c;为企业提供了有效的方式来实现网络的持续连接和稳定性。本文将探讨SD-WAN技术如何保障网络的持续连接和稳定性。 1、多路径冗余技术 SD-WAN采用了多…

一台服务器部署两个独立的mysql实例

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

激活函数Mish

paper&#xff1a;Mish: A Self Regularized Non-Monotonic Activation Function official implementation&#xff1a;https://github.com/digantamisra98/Mish 背景 在早期文献中&#xff0c;Sigmoid和TanH激活函数被广泛使用&#xff0c;随后在深度神经网络中失效。相比于…