我有一个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
。为什么这突然成为牛轧糖的一个问题?
答案 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");