Android Room 2.4.2无法识别窗口函数OVER语法报错如何解决
问题原因
该报错属于Room编译期语法校验的版本兼容问题,和运行时SQLite能力无关:
- 你使用的API31设备内置SQLite版本为3.32.2,确实原生支持窗口函数,你写的
select *, row_number() over(order by id) from mytable语句本身在SQLite层面可正常执行 - Room v2.4.2编译阶段用于做SQL语法校验的内置SQLite解析器版本较低,未收录窗口函数的语法规则,解析到
over(位置时,认为row_number()之后应该接FROM、逗号、分号等查询分隔符/关键词,因此抛出<compound operator>, FROM, GROUP, LIMIT, ORDER, WHERE, comma or semicolon expected, got '('的编译错误。
解决方案
可根据自身项目情况选择以下任意一种方案解决:
- 升级Room依赖版本到2.5.0及以上
该版本及之后的Room升级了内置SQLite解析器,原生支持窗口函数的语法校验,升级后原有SQL语句不需要任何修改即可正常编译通过,运行时在API31设备上可正常返回结果。 - 无法升级Room时,跳过指定查询的编译期校验
对包含窗口函数的DAO查询方法添加@SkipQueryVerification注解,Room会在编译阶段跳过对该条SQL的语法检查,不会抛出解析错误。由于运行时设备SQLite本身支持窗口函数,语句实际执行不会出现问题,示例代码如下:// Java写法示例 @SkipQueryVerification @Query("select *, row_number() over(order by id) from mytable") List<MyTable> getTableListWithRowNum();// Kotlin写法示例 @SkipQueryVerification @Query("select *, row_number() over(order by id) from mytable") suspend fun getTableListWithRowNum(): List<MyTable> - 如果需要兼容API30及以下的低版本Android设备(系统内置SQLite版本低于3.32,不支持窗口函数),可以引入AndroidX SQLite依赖项替换系统自带的SQLite实现,统一全版本设备的SQLite能力,再搭配上述两种方案解决编译校验问题即可。
内容的提问来源于stack exchange,提问作者yaugenka
相关产品推荐
相关产品推荐

