ContentProvider vs SQlite:相同的查询不同的结果



我有一个ContentProvider,它在调试中使用自定义CursorFacory来打印SQL查询(用于调试)。

一个特定的查询返回0行,而我知道有应该包含的行。所以我从我的日志中复制了查询,替换了绑定值,并在设备上的sqlite3 shell中运行它,得到了正确的结果。

查询代码

cr.query (contentUri, 
    Projection.columns, 
    FeedColumns.FEED_TYPE + "=? AND " +
    FeedColumns.SUB_TYPE + "=? AND " +
    ProfileUpdateFeedItem.UPDATED_FIELD + "=? AND " +
    FeedColumns.IS_NOTIFIED + "=?",
    new String[] {FeedType.USER, // 2
        WallPostData.WallPostType.PROFILE_UPDATE, // 1
        ProfileUpdateData.ProfileField.STATUS, // 0
        SQLBoolean.FALSE // 0
    }, 
    FeedColumns.CREATED + " ASC");

来自日志:

07-04 12:48:51.339    4067-4314/com.redacted.android D/DATABASE﹕ QUERY: SQLiteQuery: SELECT DISTINCT id, sender, data_1, data_2, photo, feed_type, sub_type, created, expiry, updated, comment_count, comment_unread, reaction_count, reaction_unread, sender_name, sender_photo, _id FROM wall WHERE feed_type=? AND sub_type=? AND data_1=? AND is_notified=? ORDER BY created ASC LIMIT 100
在设备

:

Enter SQL statements terminated with a ";"
sqlite> SELECT DISTINCT id, sender, data_1, data_2, photo, feed_type, sub_type, created, expiry, updated, comment_count, comment_unread, reaction_count, reaction_unread, sender_name, sender_photo, _id FROM wall WHERE  feed_type=2 AND sub_type=1 AND data_1=0 AND is_notified=0 ORDER BY created ASC LIMIT 100;
53b702b827d7482062f52b03|a7e759d78abe4bfa97045ce49a24ab57|0|Educ||2|1|1404502712279|1404761912325|1404502712279|||||Luke Skywalker|pr/e5c2c0398b267f93683c80dc5009722e|49

ContentProvider不同意,cursor.getCount()返回0。

知道为什么会这样吗?

feed_type , sub_type ,和 is_notified INTEGER列。

data_1BLOB,它为符合此查询条件的任何行存储整数,但为其他类型的数据存储字符串

当你在shell中运行时,我很惊讶你得到任何行。blob数据类型可能无法为您正确地转换键值。通常,数据库API需要一个特殊的函数来设置blob值并检索它。

这里的问题是BLOB列。它在查询中被正确地评估(表中的数据在ListView中使用,并且根据data_1data_2列的内容显示不同)。feed类别中的所有内容都被解析为植根于anstractfedobject的类层次结构的成员。

大多数同时使用data_1data_2的字段都存储文本,但有些字段(对应于上述类层次结构的子集)使用data_1作为类型枚举,UI使用它来解释存储在data_2中的值。例如,0类型表示data_2是图片id(构建url并下载),而类型1表示它是实际的文本内容。

我最终做的是用一个名为type_enumeration的整数列替换data_1,并将data_2重命名为data_1。现在我知道BLOB可能会导致这些问题,我将把data_2也更改为TEXT列。

如果将来我需要在DB中存储二进制数据,我将在列中添加一个bin_data

现在通常在适当的规范化模式中,您会使用链接表来表示这种层次结构,但在移动环境中,您希望最小化连接,以便在性能方面节省一些额外的列(至少这是我的经验)。

最新更新