android 为什么问号在查询函数中不起作用?

ca1c2owp  于 2023-04-10  发布在  Android
关注(0)|答案(2)|浏览(108)

我有一个方法:

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。为什么?它们不一样吗?

lrpiutwd

lrpiutwd1#

这是因为您将其作为字符串而不是整数进行比较,因此查询将导致像IS_FAVORITE = '1'而不是IS_FAVORITE = 1这样的WHERE条件
我认为你可以直接在选择参数中嵌入整数,因为它们不会受到注入的伤害。
可能相关:Android Sqlite selection args[] with int values

bvhaajcl

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
因此,从您尝试应用的设备上卸载应用,将代码更改为:

MovieDbScheme.IS_FAVORITE + " INTEGER"

CREATE TABLE语句中,然后重新运行。

相关问题