【问题标题】:Android: how to query SQLiteDatabase with non-string selection args?Android:如何使用非字符串选择参数查询 SQLiteDatabase?
【发布时间】:2014-01-21 14:26:24
【问题描述】:

有没有一种直接的方法来查询带有非String 类型的选择参数的SQLiteDatabase

特别是:如果 arg 是 byte[] 类型?

我能找到的最接近的东西是SQLiteDatabase.compileStatement(),它返回一个SQLiteStatement,你可以调用bindBlob等。不幸的是,SQLiteStatement 不适合查询,因为它不返回游标。

SQLiteCursor 看起来很有希望,但我不知道如何使用它。

【问题讨论】:

  • 基于 blob 的查询听起来非常低效。您确定这是编写查询的唯一方法吗?
  • 是的。它不一定是大块。
  • 有没有办法甚至 express 在 WHERE 子句中包含 BLOB 的查询?暂时忘掉Android吧:你会如何在普通的SQL中做到这一点?
  • 好问题。一个字节 literal 可以以某种方式在 sql 语句中表达吗?虽然我现在无法验证,但似乎 SQLite C api 确实允许通过准备好的语句进行查询,您可以通过 sqlite3_bind_blob 将 blob 绑定到这些语句。 link
  • 如果你想使用bindBlob()方法,你必须实现你自己的SQLiteCursorDriver

标签: android sql select sqlite


【解决方案1】:

这是 Android 数据库 API 中的一个设计错误。

queryrawQuery 只接受字符串参数。 execSQL 接受任何 Object 参数,但不返回结果。 SQLiteStatement 接受任何类型的参数,但只允许返回单个值的查询。

您可以做的是忽略参数,并手动将 blob 格式化为blob literals

cursor = db.rawQuery("SELECT a FROM b WHERE c = x'112233'", null);

【讨论】:

    【解决方案2】:

    你也可以试试

    Cursor cs = db.rawQueryWithFactory(new CursorFactory() {
                @SuppressLint("NewApi")
                @SuppressWarnings("deprecation")
                @Override
                public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery,
                        String editTable, SQLiteQuery query) {
    
                    // bind it here!...
                    query.bindBlob(1, mac);
    
    
    
                    if (Build.VERSION.SDK_INT < 11) {
                        return new SQLiteCursor(db, masterQuery, editTable, query);
                    } else {
                        return new SQLiteCursor(masterQuery, editTable, query);
                    }
                }
            }, query, null, DB_TABLE);
    

    【讨论】:

    • 不错的解决方案。但是在最后一行的参数中发送 null 将通过异常。您必须将参数作为 Array 发送
    猜你喜欢
    • 2012-09-19
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2021-09-24
    • 2017-04-30
    • 1970-01-01
    相关资源
    最近更新 更多