Android ContentProvider与SQlite:相同的查询不同的结果

Android ContentProvider与SQlite:相同的查询不同的结果,android,sqlite,android-contentprovider,Android,Sqlite,Android Contentprovider,我有一个ContentProvider,它在调试中使用一个自定义CursorFacory来打印SQL查询(用于调试) 某个查询返回0行,而我知道有些行应该包含在内。因此,我从日志中复制了查询,替换了绑定值,并在设备上的sqlite3 shell中运行它,得到了正确的结果 查询代码 cr.query (contentUri, Projection.columns, FeedColumns.FEED_TYPE + "=? AND " + FeedColumns.SUB_T

我有一个
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
在设备上:

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

知道为什么会这样吗

提要类型、子类型和被通知的是
INTEGER


data_1是一个
BLOB
,它为符合此查询条件的任何行存储一个整数,但为该表中可能包含的其他类型的数据存储字符串。

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

因此这里的问题是blob列。在查询中对其进行了正确的评估(表中的数据用于
列表视图
,并根据
数据列1
数据列2
的内容进行不同的显示)。
feed
类别中的所有内容都被解析为以AnstractFeedObject为根的类层次结构的成员

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

最后,我用一个名为
type\u enumeration
的整数列替换了
data\u 1
,并将
data\u 2
重命名为
data\u 1
。既然我知道
BLOB
会导致这些问题,我将在
data_2
中也更改为
TEXT

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


现在,通常在一个适当的规范化模式中,您会使用链接表来表示这样的层次结构,但在移动环境中,您希望最小化连接,这样就性能而言,额外的一些列更便宜(至少这是我的经验).

如果列可以是整数或字符串,则需要修复架构。显示执行查询的代码。@Gabe能否详细说明?BLOB本质上是自由格式的数据,可以用任何东西填充,但不应该由多个不同的东西填充。这就是为什么会有列,如果需要,包括可为空的列。通过将不同类型的数据保存在一列中,您最终会得到极其复杂的查询,或者用后处理代码编写部分查询。如果您的类中有一个变量,您有时不会将其用作布尔值,有时也不会将其用作字符串。列也是如此。您能否确认在ContentProvider本身中,查询返回有效值或被调用?另外,看看您的ContentProvider源代码也很好,这就是我决定在shell中运行它的原因。我想也许这团东西把我搞砸了。当查询运行并产生预期的结果时,它真的让我大吃一惊,我想我可能在寻找一个输入错误或逻辑错误。根据sqlite引用(sqlite.org/datatype3.html):BLOB。该值是一个数据块,存储与输入完全相同。如果使用已知数据查询已知值,最好为该值创建一个单独的列。如果需要查询blob中的某些内容,推荐的方法是使用用于blob的sqlite绑定api从blob读取数据,并根据数据的任何结构比较数据。