如何在Android中使用整数类型搜索数据库

时间:2013-02-18 16:17:12

标签: android sqlite

自Android中的SQLite开始以来,这个问题困扰着我。选择参数为Strings。什么?为什么呢?

我们来看看我的问题。我有一个正确填充的数据库:

sqlite> select count (*) from issues where project_id = 1;
3819

大。我们来看看代码:

public Cursor selectAllCursor(final long projectId) {
    final String selection = projectId > 0 ? KEY_PROJECT + " = ?" : null;
    final String[] selArgs = projectId > 0 ? new String[] {
        Long.toString(projectId)
    } : null;

    final Cursor c = mDb.query(TABLE_ISSUES, null, selection, selArgs, null, null, null);
    c.moveToFirst();
    return c;
}

嗯,返回Cursor是空的。为什么呢?

sqlite> select count (*) from issues where project_id = '1';
0

嗯,这就是原因。

我发现的唯一解决方案是:

public Cursor selectAllCursor(final long projectId) {
    final String selection = projectId > 0 ? KEY_PROJECT + " = " + projectId : null;
    final String[] selArgs = null;

    final Cursor c = mDb.query(TABLE_ISSUES, null, selection, selArgs, null, null, null);
    c.moveToFirst();
    return c;
}

它有效,但我觉得这很难看 为什么选择参数不是Object而不是String的数组? Android框架将测试对象类型,如果它是一个整数(int / long),它会告诉SQLite将其视为整数。

2 个答案:

答案 0 :(得分:1)

参数对于避免字符串格式化问题(包括SQL注入攻击)非常有用。 对于其他类型,您没有这样的问题。

但这仍然意味着您必须使用完全不同的代码,具体取决于值的类型。 此外,如果您使用compileStatement可以使用其他类型作为参数,但SQLiteStatement仅适用于单个值(1 x 1)结果集。

这只是简单的错误的API设计。

如果您将表格列声明为INTEGER,则SQLite的type affinity rules会自动将该值转换回数字。 但是,这仅适用于Column = ?等直接比较。

答案 1 :(得分:0)

你是对的,documentation非常明确,参数将始终绑定为字符串。不确定为什么(因为那是你的实际问题:-)),但无法找到解决方法。

  

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

使用String.format做一个“更好”的方式来做你所拥有的东西? 例如

String selection = String.format("%s = %d", KEY_PROJECT, projectId )