Android Nougat中的SQLite查询不向后兼容

时间:2016-09-30 08:51:13

标签: android sqlite android-7.0-nougat

我有一个SQLite查询,在Android Nougat上按_id返回记录,但 在Android前Nougat上返回记录。

当我将调试器附加到Nougat模拟器并开始探索时,我会观察到以下内容:

原始代码

readableDatabase.query("report_view", null, "_id = ?", new String[]{"2016309001"}, null, null, null).getCount()

结果:0

四处寻找/评估表达

readableDatabase.rawQuery("SELECT * FROM report_view WHERE _id = 2016309001", null).getCount()

结果:1​​

启用SQLite日志会导致(注意单引号):

V/SQLiteStatements: /data/user/0/xyz/bla.db: "SELECT * FROM report_view WHERE _id = '2016309001'"

对于Nougat上的非原始查询。我似乎无法在pre-Nougat(Marshmallow)设备上启用SQLite日志。

所以看起来这个问题是由Android用单引号围绕参数引起的。 _id列的类型为integer。引号括起的值的类型为string。为什么这突然成为牛轧糖的一个问题?

2 个答案:

答案 0 :(得分:1)

除非我弄错了你的原始代码将日期参数显式地作为字符串(new String [])传递,并且查询方法的Android文档,selectioArgs参数状态

  

selectionArgs 字符串:您可以在选择中包含?s   替换为selectionArgs中的值,以便它们出现   在选择中。 这些值将绑定为字符串

因此,如果你想要除了字符串以外的东西,你应该执行强制转换,或者更好,不要使用查询和rawQuery方法,而是使用预处理语句(SQLiteStatement),这将允许你指定类型参数。

还有'?'在日志中被替换应该是用于记录目的的“假”替换(至少我希望它是用于记录目的的伪替换,因为Android应该在那里使用绑定参数,而不是在查询中替换它)。

最后,Android中的字段类型仅用于type affinity,因此即使您在表中将字段声明为“整数”,如果使用了Query方法及其仅字符串,也完全有可能参数,你实际上最终得到了记录中的字符串。

答案 1 :(得分:0)

理论上,SQLite的行为应该不同。您可能正在使用不同的表定义,从而产生不同的affinity

无论如何,您为query函数提供的参数是一个字符串,因此数据库将其作为字符串处理也就不足为奇了。

如果要为数据库指定编号,则必须将参数设为数字。 并且Android框架对大多数数据库函数都不允许这样做,因此您必须将其直接放入字符串中:

db.query("report_view", null, "_id = " + "2016309001", null, null, null, null).getCount();

请注意,计算行数为helper function

DatabaseUtils.queryNumEntries(db, "report_view", "_id = " + "2016309001");