Android Room(SQLite) too many SQL variables异常
SQLiteException
- 一、解决办法
- 1. 修改数据库语句
- 2. 分批执行
- 二、问题根源
转载请注明出处: https://blog.csdn.net/hx7013/article/details/143198862
在使用 Room 或其他基于 SQLite 的 ORM 框架时,批量操作如 IN 或 NOT IN 查询可能会触发 android.database.sqlite.SQLiteException: too many SQL variables 异常。该问题源于 SQLite 的 IN 和 NOT IN 子句会将数据转换为 ... IN (?, ?, ? ...) 的形式,而 SQLite 对可绑定的参数数量是有限制的。在 Android 系统中,这一限制是由系统内置的 SQLite 版本所固化,无法直接修改,除非你自行编译并替换 SQLite 库。因此,当查询的条件过多时,超过了这个限制,就会抛出该异常。
一、解决办法
由于 SQLite 内部对于参数量的限制本身是相对较高的(999或32766),大部分能引发此问题的场景通常是在执行 UPDATE 或 DELETE 操作时。
1. 修改数据库语句
可以通过优化查询语句来减少参数数量,特别是在使用 IN 或 NOT IN 的查询中。例如,提炼参数或改为单调执行循环调用,避免 IN 的使用等。由于每个项目的查询需求不同,具体的修改方式需根据实际情况进行,此处不做深入讨论。
2. 分批执行
当参数数量过多时,可以将大批量的操作拆分为多个小批量的操作。以下举例说明如何分批处理:
@Query("DELETE FROM sync_data WHERE uuid IN (:uuids)")
suspend fun delete(uuids: List<String>): Int@Query("UPDATE sync_data SET is_delete = 1, delete_time = :deleteTime WHERE uuid IN (:uuids)")
suspend fun softDelete(uuids: List<String>, deleteTime: Long = System.currentTimeMillis()): Int
上面两个查询分别执行物理删除和逻辑删除操作。为了代码简洁和执行效率,我们通常会过滤出需要删除的 uuid,并通过 IN 执行批量操作。然而,如果 uuids.size > 999,SQLite 会抛出 android.database.sqlite.SQLiteException: too many SQL variables 异常。在这种情况下,可以使用分批执行的方式避免异常:
调用示例:
internal const val SQL_BATCH_SIZE = 500...
/*** bolg: https://blog.csdn.net/hx7013*/
private suspend fun softDeleteByUuids(newUuids: Set<String>): Boolean = try {// 加载未删除的 UUID,并过滤掉新 UUIDval overdueUuids = syncDataDao.loadNonDeletedUuids().filter { it !in newUuids }if (overdueUuids.isNotEmpty()) {// 使用 chunked 将列表拆分,每批执行软删除操作val deleteRows = overdueUuids.chunked(SQL_BATCH_SIZE).sumOf { syncDataDao.softDelete(it) }// 比较实际删除的行数是否与期望一致overdueUuids.size == deleteRows} else {true}
} catch (e: Exception) {e.printStackTrace()false
}
在这个例子中,使用 chunked 方法将 List 按照指定大小分批处理,每批执行数据库操作,并通过 sumOf 计算总的影响行数。这种方式避免了参数过多的问题,并确保在大数据集的情况下也能顺利执行批量操作。
其它SELECT、DELETE 等逻辑类似。
二、问题根源
其实,该问题不仅限于 Android 环境,在所有使用 SQLite 的场景中都会出现。
在 SQLite 中,主机参数 是 SQL 语句中的占位符,通过 sqlite3_bind_XXXX() 方法进行绑定。常见的主机参数格式包括问号 (?)、命名参数(以 :、$ 或 @ 为前缀),以及编号参数(如 ?123)。
每个 SQL 语句中的主机参数都会被分配一个编号,默认从 1 开始递增。如果使用 ?123 形式,则参数的编号是问号后的数字。需要注意的是,SQLite 为每个主机参数分配内存,编号从 1 到最大的参数编号。如果 SQL 语句中包含类似 ?1000000000 这样编号巨大的参数,会导致大量内存消耗,可能会使主机资源耗尽。
为避免这种问题,SQLite 通过 SQLITE_MAX_VARIABLE_NUMBER 限制了单个 SQL 语句中主机参数的最大数量。如果需要修改该值,可以在运行时使用 sqlite3_limit(db, SQLITE_LIMIT_VARIABLE_NUMBER, size) 来调整最大允许的参数数量。
这个默认的大小在 SQLite 3.32.0 之前的版本(2020-05-22 发布),主机参数的默认最大值为 999;而在 3.32.0 及之后的版本中,这一限制提升到了 32766。
如果有定制需求,可以自行编译SQLite,修改SQLITE_LIMIT_VARIABLE_NUMBER参数。
详细可以查看:
https://www.sqlite.org/limits.html 第9节或 https://www.sqlite.org/c3ref/c_limit_attached.html#sqlitelimitvariablenumber 的说明。
转载请注明出处: https://blog.csdn.net/hx7013/article/details/143198862
相关文章:
Android Room(SQLite) too many SQL variables异常
SQLiteException 一、解决办法1. 修改数据库语句2. 分批执行 二、问题根源 转载请注明出处: https://blog.csdn.net/hx7013/article/details/143198862 在使用 Room 或其他基于 SQLite 的 ORM 框架时,批量操作如 IN 或 NOT IN 查询可能会触发 android.database.sqli…...
sentinel原理源码分析系列(八)-熔断
限流为了防止过度使用资源造成系统不稳,熔断是为了识别出”坏”资源,避免好的资源受牵连(雪崩效应),是保证系统稳定性的关键,也是资源有效使用的关键,sentinel熔断插槽名称Degrade(降级),本人觉得应该改为熔…...
安全见闻(4)——开阔眼界,不做井底之蛙
内容预览 ≧∀≦ゞ 安全见闻四:操作系统安全机制深度解析声明操作系统机制1. 注册表2. 防火墙3. 自启动与计划任务4. 事件日志5. 内核驱动与设备驱动6. 系统服务7. 进程与线程8. 系统编程 从操作系统机制看病毒设计1. 自启动:病毒如何在系统启动时运行&a…...
(二十二)、k8s 中的关键概念
文章目录 1、总体概览2、第一层:物理机、集群、Node、Pod 之间的关系2、第二层:命名空间 Namespace3、定义4、控制平面(Control Plane)5、特别的概念 Service6、Deployment 经过 之前几篇文章对 k8s 的实践,结合实践&…...
python基础综合案例(数据可视化-地图可视化)
1.基础地图使用 注意写名字的时候要写全名,比如上海市不能写出上海,不然看不到数据 鼠标点击即可看到数据 设置属性的时候不要忘记导包 # 演示地图可视化的基础使用 from pyecharts.charts import Map from pyecharts.options import VisualMapOpts # 准…...
基于SpringBoot足球场在线预约系统的设计与实现
💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...
操作系统笔记(二)进程,系统调用,I/O设备
什么是进程? 一个正在执行的程序一个包含运行一个程序所需要的所有信息的容器进程的信息保存在一个进程表中( Process Table)。进程表中的每一项对应一个进程,称为进程控制块(Process control block,PCB)。 PCB信息包括: 用户ID(UID)、进程ID(PID)…...
DevOps实践:在GitLab CI/CD中集成静态分析Helix QAC的工作原理与优势
基于云的GitLab CI/CD平台使开发团队能够简化其CI/CD流程,并加速软件开发生命周期(SDLC)。 将严格的、基于合规性的静态分析(如Helix QAC所提供)作为新阶段添加到现有的GitLab CI/CD流程中,将进一步增强SD…...
前端面试题-token的登录流程、JWT
这是我的前端面试题的合集的第一篇,后面也会更新一些笔试题目。秋招很难,也快要结束了。但是,不要放弃,一起加油^_^ 一、token的登录流程 1.客户端用账号密码请求登录 2.服务端收到请求,需要去验证账号密码 3.验证成…...
【软考高级架构】关于分布式数据库缓存redis的知识要点汇总
一.分布式数据库的含义 分布式数据库缓存指的是在高并发的环境下,为了减轻数据库的压力和提高系统响应时间,在数据库系统和应用系统之间增加一个独立缓存系统。 二.常见的缓存技术 (1)MemCache: Memcache是一个高性能的分布式的内…...
构建自然灾害预警决策一体化平台,筑牢工程安全数字防线
近年来,国家和部委也强调了要切实加强地质灾害监测预警。作为国内智慧应急领域的先行者,Mapmost持续探索利用数字孪生技术,推进自然灾害风险预警精细化,强化对监测数据的综合分析和异常信息研判处置。建立健全区域风险预警与隐患点…...
随机题两题
逆序对 题目 给定一个数组,求其中有多少逆序对,要求时间复杂度不超过nlogn。 思路 使用归并排序的分治思想,将数组递归地分为左右两部分。在合并两个有序子数组时,若左侧数组中的某个数大于右侧数组中的某个数,则可…...
信息安全工程师(69)数字水印技术与应用
前言 数字水印技术是一种在数字媒体中嵌入特定信息的技术,这些信息可以是版权信息、元数据等。 一、数字水印技术的定义与原理 数字水印技术(Digital Watermarking)是将一些标识信息(即数字水印)直接嵌入数字载体&…...
知识点框架笔记3.0笔记
如果基础太差,搞不清基本交规的(模考做不到60分),建议找肖肖或者小轩老师的课程看一遍,内容差不多(上面有链接),笔记是基于肖肖和小轩老师的科目一课程以及公安部交管局法规…...
Android组件化开发
Android组件化开发 组件化开发概念组件化开发的由来组件化开发有什么优势?组件化开发如何拿到入口参数?如何解决相同资源文件名合并的冲突?模式切换,如何使APP在单独调试跟整体调试自由切换?多个Module之间如何引用一些共同的library以及工具类?我们如何实现依赖关系及组…...
centos-LAMP搭建与配置(论坛网站)
文章目录 LAMP简介搭建LAMP环境安装apache(httpd)安装mysql安装PHP安装php-mysql安装phpwind LAMP简介 LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写:Linux操作系统,网页服务器Apache,…...
Python 实现日期计算与日历格式化输出
目录 一、引言 二、需求分析 三、实现思路 四、代码实现 五、代码分析 六、测试与验证 七、总结与展望 在日常的编程中,我们经常会遇到与日期相关的问题,比如计算两个日期之间的天数差、确定某个特定日期是星期几以及格式化输出日历等。本文将详细…...
npm install 安装很慢怎么办?
安装源管理器nrm sudo npm install -g nrm #macOSnpm install -g nrm #Windows以管理员身份运行 安装完毕之后通过以下命令可以切换你想要的源 nrm ls #查看源列表* npm ---------- https://registry.npmjs.org/yarn --------- https://registry.yarnpkg.com/tencent ------…...
【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据)
【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据) 数据准备:以叶面积指数LAI为例QGis实操:基于GIS4WRF插件将geotiff数据转为tiff警告:GIS4WRF: Input layer had an unexpected …...
python+大数据+基于Hadoop的个性化图书推荐系统【内含源码+文档+部署教程】
博主介绍:✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ 🍅由于篇幅限制,想要获取完整文章或者源码,或者代做&am…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
