【问题标题】:Android: SQLite Query not binding integer parameters?Android:SQLite 查询不绑定整数参数?
【发布时间】:2011-01-31 05:04:49
【问题描述】:

在 Android 平台 (2.2) 上使用参数查询数据库时遇到问题。我创建了这样的表:

db.execSQL("CREATE VIRTUAL TABLE " + Msg._TABLE_NAME + " USING FTS3 ("
            + Msg._ID + " INTEGER, "
            (...)
            + Msg.READ + " SHORT DEFAULT 0,"
            + Msg.URGENT + " SHORT DEFAULT 0"
            + ");");

然后我尝试使用参数化查询进行查询:

String[] columns = new String[] {Msg.ROWID, Msg.TITLE, Msg.READ, Msg.URGENT};
(...)
getContentResolver().query(Msg.CONTENT_URI, columns, 
    Msg.URGENT + "=? AND " + Msg.READ + "=?" + , whereArgs, null);

whereArgs 因每个查询而异:

String[] urgentUnread = new String[]{"1", "0"};
String[] regularUnread = new String[]{"0", "0"};

但不管它返回 0 结果/行,即使数据存在。内容提供者不会更改参数,并且使用 QueryBuilder 以及“直接”调用查询时查询不会返回任何内容:

Cursor c = db.query(tables, columns, where, whereArgs, groupBy, having, orderBy, limit);

如果我只做字符串连接,查询就有效:

getContentResolver().query(Msg.CONTENT_URI, columns, 
    Msg.READ + "=0 AND " + Msg.URGENT + "=1", null, null);

但这似乎破坏了参数查询的目的,而且缓存起来很讨厌。 Dalvik 抱怨(在进行大量查询之后)缓存中没有空间用于查询,具有讽刺意味的是,它告诉我使用带有“?”的参数化查询。我很乐意,相信我:)

我知道 JavaDoc 声明参数被绑定为 StringS,但我简直不敢相信...因为那将是主要的...咳咳,... WTF

我哪里出错了?

提前致谢。

【问题讨论】:

    标签: android sqlite parameters


    【解决方案1】:

    这是 OP,我正在进一步研究和试验,得出的结论是 FTS3 应该受到责备。由于我需要数据为searchable by fulltext,因此我正在创建VIRTUAL TABLE USING FTS3,然后参数绑定失败。

    由于我不想直接查询影子表(Msg_content),我的解决方案是将数据拆分为2个相关表:

    db.execSQL("CREATE TABLE " + Msg._TABLE_NAME + " (" +
        Msg._ID + PRIMARY_KEY_AUTOINC + 
        Msg.PRIORITY + " TEXT," +
        Msg.RECEIVED + " INTEGER," +
        Msg.MOBILE_STATUS + " INTEGER DEFAULT 0," +
        Msg.READ + " SHORT DEFAULT 0," +
        Msg.FLASH + " SHORT DEFAULT 0" +
    ");");
    
    db.execSQL("CREATE VIRTUAL TABLE " + MsgText._TABLE_NAME + " USING FTS3 (" + 
        MsgText._ID + PRIMARY_KEY +
        MsgText.TITLE + " TEXT," +
        MsgText.CONTENT + " TEXT," +
        MsgText.KEYWORDS + " TEXT," +
        "FOREIGN KEY(" + MsgText._ID + ") " +
        "REFERENCES " + Msg._TABLE_NAME + "(" + Msg._ID + ") " +
    ");");
    

    然后我创建了 View 以供查询使用:

    db.execSQL("CREATE VIEW IF NOT EXISTS " + View.MSG_CONTENT +
        " AS SELECT " +
        Msg._TABLE_NAME + "." + Msg._ID + ", " +
        Msg._TABLE_NAME + "." + Msg.READ + ", " +
        Msg._TABLE_NAME + "." + Msg.FLASH + ", " +
    (...)
        MsgText._TABLE_NAME + "." + MsgText.TITLE + ", " +
        MsgText._TABLE_NAME + "." + MsgText.CONTENT +
        " FROM " + Msg._TABLE_NAME + ", " + MsgText._TABLE_NAME +
        " WHERE " + Msg._TABLE_NAME + "." + Msg._ID + "=" +
        MsgText._TABLE_NAME + "." + MsgText._ID);
    

    这对我来说非常有效,因为我可以使用参数查询数据并在需要时进行全文搜索。查询性能与仅使用一张表时相同。

    我希望这对可能遇到相同问题的其他人有所帮助。

    干杯,
    佩斯

    附:显然检查了 Meta 和 it is OK to reply to self

    【讨论】:

    • 不仅好的,而且实际上受到鼓励 - 如果没有人提出解决方案,而您找到了解决方案,感谢分享。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-26
    • 2016-06-27
    相关资源
    最近更新 更多