- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在测试我的一个应用程序的 Android 5.0 兼容性时,我发现 一个 我的两个 SQL 查询 不 在 Lollipop 上不再按预期工作。与旧的 Android 版本相比,我的两个问题导致 Lollipop 的结果明显不同。
下面,我将更深入地描述这些问题及其解决方案,以防您遇到类似问题。
我的主要问题很简单:这些不向后兼容的更改是否记录在案?
以下查询似乎不再适用于 Lollipop:
SELECT title FROM ents JOIN ctt ON ctt.docid = ents.cttId WHERE (ctt MATCH '*ads*');
它不再返回任何结果,在 Lollipop 之前它确实返回了(当然,使用相同的数据库和相同的数据)。
如 this question 中所述,例如, MATCH 仅匹配字符串前缀。确实如此,搜索词前面的“*”在 Android < 5.0 上被忽略了。
然而,Lollipop 的 SQLite 不喜欢第一个 '*' 并且不为此查询返回任何内容。我不得不将查询更改为以下内容以使其再次工作:
SELECT title FROM ents JOIN ctt ON ctt.docid = ents.cttId WHERE (ctt MATCH 'ads*');
(我正在使用 FTS3 进行全文搜索。)
简短的故事: GROUPing BY 原始名称引用的别名列与使用 Android 特定的“COLLATE LOCALIZED”的 ORDER BY 结合会在 Lollipop 上引发错误,但适用于以前的版本。哇!? :-)
长篇大论:
故事从一个相当大的自动生成查询开始,所以我对其进行了修改、简化和缩短到导致问题的部分。我知道查询没有多大意义,如下所示,但它说明了问题。
SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT types.text AS title FROM types) AS inner
GROUP BY inner.title
UNION SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT types.text AS title FROM types) AS inner
GROUP BY inner.title
ORDER BY title2 COLLATE LOCALIZED ASC
上面的查询适用于 < 5.0 的 Andriod,但在 Lollipop 中会出错:
Error: no such column: inner.title
OK, I aliased "inner.title" with "title", so I tried changing the "GROUP BY inner.title" to "GROUP BY title" which really is the solution for Lollipop's SQLite:
SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT types.text AS title FROM types) AS inner
GROUP BY title
UNION SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT types.text AS title FROM types) AS inner
GROUP BY title
ORDER BY title2 COLLATE LOCALIZED ASC
(顺便说一句,在 this answer 中,您可以找到 Android 中使用的 SQLite 版本的概览)
现在有趣的部分来了:如果在 ORDER BY 子句中删除了 Android 特定的“COLLATE LOCALIZED”,那么一切都会开始工作,即使是“GROUP BY inner.title”:
SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT indsntyps.text AS title FROM indsntyps) AS inner
GROUP BY inner.title
UNION SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT indsntyps.text AS title FROM indsntyps) AS inner
GROUP BY inner.title
ORDER BY title2 ASC
我的 Lollipop 体验基于使用 Android 5.0 - API Level 21 ARM 系统镜像的 SDK 模拟器中的测试。
对我来说,这个问题似乎是 Android 特有的 SQLite 错误。或者有人可以向我解释这个(在我看来)奇怪的行为吗?或者,再一次,这甚至在某个地方有记录吗? :-)
提前致谢!
最佳答案
无论如何,我都不是 SQLite 专家,我假设您打算让这个问题在很大程度上是修辞,但请允许我提供一些想法。
正如你已经指出的,MATCH
only considers prefix terms .使用星号作为前缀(如果您愿意的话)会导致意外和不可预知的行为,这并不奇怪。
这似乎是一个有趣的错误。不过,您可以尝试使用 EXPLAIN QUERY PLAN
来尝试诊断它。
显然,我没有告诉你任何你不知道的事情。但是,您的“问题”是关于文档的。对于初学者,SQLite release notes can be found here .它们通常非常详细地说明版本之间的变化。
您的第一个问题实际上是编程错误。有关如何使用 FTS 前缀的文档已经存在。你不会得到关于为什么你的特定语法停止工作的解释。可以说,它从一开始就不应该起作用。
LOCALIZED
问题可能是一个错误,因此它缺乏“文档”(不过,我鼓励您将其报告给 Google)。还要记住,SQLite 是 Android 核心的一部分,它不仅有自定义(如 LOCALIZED
),还有原生 Java 绑定(bind)。底层 SQLite 核心实现和绑定(bind)都可能随着每个版本而改变。这让我想到了我的主要观点:
考虑使用私有(private) SQLite 实现来部署您的应用。这样做的说明can be found here .这将使您能够控制您的应用程序使用的 SQLite 版本,并让您可以很好地控制如何以及何时升级它。但是,这确实是有代价的,因为您丢失了 LOCALIZED
关键字,我相信绑定(bind)只支持 API 15 或更高版本。
关于Android Lollipop - 改变 SQLite 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26816561/
我使用工具栏是为了在我的应用程序中进行 Material 设计。一切正常,但除了更改菜单项文本颜色时,我完全无法接受该解决方案。我还张贴了我在申请中使用的文本和代码的屏幕截图,供您引用。我尝试了几种替
看起来 FloatingActionButton 在 Android 4.0 和 Lollipop 上无法正常工作。正如您在下图中看到的那样,在 Android Lollipo 上,阴影缺失,而在 A
SDK 升级到 Android 5 后,我无法使用 Intel 硬件加速执行管理器: $ android-sdk-macosx/tools/emulator -avd AVD_for_LowMemor
SDK升级到Android 5后,无法使用Intel Hardware Accelerated Execution Manager: $ android-sdk-macosx/tools/emulat
我有不同 draw9patch png 作为背景的按钮。目前按钮由 selector 控制,看起来像这样: 对于 Android Lollipop,他们有一个用于触摸效果的
我尝试在 Pre-Lollipop 设备上运行我的应用程序。但是这段代码向我显示了 Pre-Lolliop 和 Lollipop 设备的相同错误。 如果我将“android:”添加到样式中(如样式 2
我实现了一个自定义的 SurfaceView 来绘制相机预览,并在其上完成了所有捕获和手动对焦操作。它在 Pre-Lolipop 设备上运行良好,但问题是它在 Lollipop 设备上崩溃。 发生的最
风格 @color/my_primary_color @color/my_primary_dark_color @color/accent 布局
我想在 Lollipop 设备中显示较旧的时间选择器(如 Lollipop 设备之前的时间选择器)。可以 这是可能的。 最佳答案 您可以通过将 timePickerMode 属性设置为“spinner
嗨,所以我有点困惑,想知道是否有人能指出我正确的方向。 在 Lollipop 和 pre-lollipop 上使用 Google Play 商店 您会在 Lollipop 上看到可选择的 View 具
如果我们希望使用 Material Design 的应用同时支持 Lollipop 和 Lollipop 之前的设备,以下哪种方法是正确的? 单独使用 Android 支持库:仅对整个应用程序使用支持
我正在使用 appcompat/support-v7 中引入的新工具栏小部件。我想根据用户是否向上/向下滚动页面来隐藏/显示工具栏,就像在新的 Google Playstore 应用程序或 NewsS
我的数据库中有一个 .mhtml 文件作为字节数组。我写了下面的代码,它在 Lollipop 之前的设备上运行良好。但它不适用于 Lollipop 和棉花糖。 代码:- String p
根据标题,我能够在下面的 Lollipop 中成功读取/写入数据,但在 Lollipop 中多次读取/写入失败。 这就是我读/写数据的方式: boolean isRead= getmBluetooth
我刚刚在 Android Studio 上安装了 Android 5,并在模拟器上进行了第一次运行。我发现“API Demos”应用程序非常有趣,我想找到代码。我说的是这个应用程序: 有人知道我在哪里
我正在关注 this tutorial在 Android Material Design 中使用颜色(我的 ActionBar 和 StatusBar)。我确实按照教程进行操作,但没有反射(refle
在我的应用程序中,用户可以通过它调用任何号码,我正在启动蓝牙 audioManager.setBluetoothScoOn(true); audioManager.startBluetoothSco(
我正在我的 android 应用程序中实现 Google map API v2。该应用程序在所有设备上都可以正常工作,但在 Lollipop 设备上却不行。应用程序在 Lollipop 中崩溃。我确实
我正在开发一个项目,其中有一个日期选择器。我正在尝试为其设置最大日期和最短日期。最短日期是今天之后 1 天,最大日期是今天之后 11 天。但问题是在 Lollipop 设备中,最后一个最大日期显示为可
我正在使用嵌入式无线系统,它以定义的时间间隔生成数据包。目的是检测设备/系统何时重新启动。为此,我读到 Lollipop 序列编号是最适合此目的的编号方案。 “在此编号方案中,序列号从负值开始,增加直
我是一名优秀的程序员,十分优秀!