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

时间:2014-07-04 20:11:24

标签: android sqlite android-contentprovider

我有一个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_1 BLOB,它为符合此查询条件的任何行存储整数,但存储字符串对于此表中可能包含的其他类型的数据。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

所以这里的问题是BLOB专栏。它在查询中被正确评估(表中的数据用于ListView,并根据data_1data_2列的内容以不同方式显示。 feed类别中的所有内容都会被解析为以AnstractFeedObject为根的类层次结构的成员。

同时使用data_1data_2的大多数字段都会在两者中存储文本,但某些字段(与所提及的类层次结构的子集相对应的字段)使用data_1作为类型枚举UI用于解释存储在data_2中的值。例如,0类型表示data_2是图片ID(构建网址和下载),而类型1表示它的实际文本内容。

我最终做的是将data_1替换为名为type_enumeration的整数列,并将data_2重命名为data_1。既然我知道BLOB可能会导致这类问题,我也会data_2再次转到TEXT列。

如果将来某个时候我需要在数据库中存储二进制数据,我会在列中添加bin_data

现在通常在正确的规范化模式中,您使用链接表来表示此类层次结构,但在移动环境中,您希望最小化连接,以便在性能方面更少一些额外的列(至少是&# 39;是我的经历)。