【问题标题】:Get current date data from Content Provider从 Content Provider 获取当前日期数据
【发布时间】:2014-08-20 08:34:16
【问题描述】:

我必须根据当前月份从 ContentProvider 获取数据。为了获取数据,我使用了以下查询:

SELECT * FROM Festivals
WHERE strftime('%Y-%m-%d',fest_date) >= date('now','-6 days') AND
strftime('%Y-%m-%d',fest_date)<=date('now') order by fest_date

我尝试在 CursorLoader 中编写如下:

new CursorLoader(this, FestivalContract.Festivals.CONTENT_URI, 
            PROJECTION, "strftime('%Y-%m-%d',fest_date)>=? AND strftime('%Y-%m-%d',fest_date)<=?", new String[] { "date('now','-6 days')", "date('now')" },
            FestivalContract.Festivals.FestivalColumns.FEST_NAME + " asc");

但是,它返回了所有记录。我找不到我的代码有什么问题。

【问题讨论】:

  • 您将fest_date 变量作为字符串传递。 "strftime('%Y-%m-%d',fest_date)&gt;=? AND strftime('%Y-%m-%d',fest_date)&lt;=?", new String[] { "date('now','-6 days')", "date('now')" }
  • 对不起,我的错,我忘了说,fest_date 是我的数据库表中的一列的名称。
  • 了解,但有任何替代方法。因为,我不想一次获取全年的数据,因为这只会浪费。我必须在日历上突出显示将有任何活动的日期
  • @Downvoter 有理由投反对票吗?
  • 只需尝试在查询参数中输入一些值而不是 new String[] { "date('now','-6 days')", "date('now')" } 以查看它是否有效,这样您就可以检查您的问题是否存在。

标签: android sqlite android-contentprovider android-cursorloader


【解决方案1】:

可能你在内容提供者中的查询方法是这样的:

SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        // check if the caller has requested a column which does not exists
        checkColumns(projection);
        // Set the table
        queryBuilder.setTables(MessageTable.TABLE_NAME);
        int uriType = uriMatcher.match(uri);
        switch (uriType) {
            case MESSAGES:
                break;

            case MESSAGE_ID:
                // adding the ID to the original query
                queryBuilder.appendWhere(MessageTable.COLUMN_ID + "=" + uri.getLastPathSegment());
                break;

            case BROADCAST_MESSAGES:
                groupBy = MessageTable.COLUMN_MESSAGE_ID;
                break;

            default:
                throw new IllegalArgumentException("Unknow URI: " + uri);

如果您使用 queryBuilder 无法实现您的目标。 您有两种解决方法:

1- 将您的日期以长格式存储在数据库中。例如,您的节日日期是 unix 格式的日期,这意味着您应该将每个日期作为长数字存储在数据库中。然后像这样在 cursorloader 中编写查询:

new CursorLoader(this, FestivalContract.Festivals.CONTENT_URI, 
        PROJECTION, "fest_date>=? AND fest_date<=?", new String[] { System.currentTimeMillis(), System.currentTimeMillis() - 6 * 24 * 3600 * 1000)", "" },
        FestivalContract.Festivals.FestivalColumns.FEST_NAME + " asc");

2- 第二种解决方案是自定义您的 ContentProvider 并为您要进行的此特殊查询添加不同的 Content_Uri,然后在您的提供程序的 query 方法中检查您是否正在查询此特殊 uri ,然后不要使用不允许您运行 sql 方法的QueryBuilder,只需在内容提供程序中拥有的数据库对象上执行查询字符串,如下所示:

return database.rawQuery(your_query_string_with_sql_methods, new String['your_params_or_whatever]);

【讨论】:

  • 顺便说一下,我更喜欢第一种方法。
  • 是的,我做到了。游标仍然返回所有记录。不明白为什么。
  • 即使不使用strftime 方法?!
  • 是的,这次我将日期转换为长日期。
  • 所以,你应该仔细检查你的代码,我猜你在某个地方犯了一个简单的错误。
【解决方案2】:

参数(?)用于你不想被执行的字符串。

但您想执行date 函数。只需将它们直接放入 SQL 查询中即可。

【讨论】:

  • 但是,Content Provider 不支持rawQuery。那么,我该如何实现呢?你的意思是说,单独执行日期函数并将它们的输出作为选择参数传递?
  • 否,将字符 ? 替换为 date(...)。 (date 是一个类似strftime 的函数。)
  • 已经尝试过了,但是由于strftime(),它没有给出想要的输出。尽管,我在单独的查询中执行 strftime(),但我不知道如何在投影中传递该输出。我需要将日期格式化为服务器一起发送的日期和时间。
  • 你问题中的第一个查询真的有效吗?
  • 是的,在 sqlite 语法中。
猜你喜欢
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
相关资源
最近更新 更多