我有一个方法:
public int getCountOfFavoriteMovies(){
Cursor cursor = mDatabase.query(
MovieDbScheme.NAME,
null,
MovieDbScheme.IS_FAVORITE + " = 1",
null,
null,
null,
null
);
try{
return cursor.getCount();
}
finally {
cursor.close();
}
}
它返回7,但如果我用下面的代码替换它:
Cursor cursor = mDatabase.query(
MovieDbScheme.NAME,
null,
MovieDbScheme.IS_FAVORITE + " = ?",
new String[]{Integer.toString(1)},
null,
null,
null
);
因为某种原因它返回0。为什么?它们不一样吗?
2条答案
按热度按时间lrpiutwd1#
这是因为您将其作为字符串而不是整数进行比较,因此查询将导致像
IS_FAVORITE = '1'
而不是IS_FAVORITE = 1
这样的WHERE条件我认为你可以直接在选择参数中嵌入整数,因为它们不会受到注入的伤害。
可能相关:Android Sqlite selection args[] with int values
bvhaajcl2#
Datatypes In SQLite是一个复杂的概念,您必须仔细研究它以避免类似的问题。
您已经定义了没有任何数据类型的列
MovieDbScheme.IS_FAVORITE
,这意味着它没有类型关联。当你在
query()
方法的selection
参数中使用?
占位符时,这些占位符将被selectionArgs
的值作为字符串替换(所以如果你传递1
,它将被'1'
替换)。这意味着发生的比较将在没有关联的列和字符串之间进行。
在这种情况下,SQLite不执行亲和转换,
1 = '1'
将返回false
,因为:对于SQLite,INTEGER值始终小于TEXT值
(from比较例)
您应该做的是将列
MovieDbScheme.IS_FAVORITE
定义为INTEGER
(如果SQLite版本是3.23.0+,则为BOOLEAN
),在这种情况下,SQLite将执行亲和转换,并将表达式1 = '1'
的两个操作数作为整数进行比较。参见demo。
因此,从您尝试应用的设备上卸载应用,将代码更改为:
在
CREATE TABLE
语句中,然后重新运行。