【问题标题】:How to query recurring appointments stored as iCal RRULE in a database table?如何查询在数据库表中存储为 iCal RRULE 的定期约会?
【发布时间】:2017-02-06 19:45:03
【问题描述】:

如果我有一个包含以下列的约会表,我如何查询规则以提取在特定日期或两个日期之间发生的约会?

Appointments
------
id
name
dt_start
dt_end
rrule

例如,假设我有一个约会,从 2016 年 9 月 28 日开始,到 2017 年 4 月 28 日结束,它每 2 周发生一次,从星期一、星期五到 2017 年 4 月 28 日。 以下是 RRule:

RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20170428T230000Z;BYDAY=MO,FR EXDATE:20170414T023000Z

因此,使用上面的示例,上述约会的某些日期将包括以下内容:

2016-09-30 FRI
2016-10-10 MO
2016-10-14 FRI
2016-10-24 MO

现在如何使用 SQL 或任何其他方法查询此表以提取 2016 年 10 月 10 日发生的所有约会?

为了记录,这将在 C# asp.net 和 SQL 服务器中完成。是否有可用于解析和查询 rrule 的 C# 或 SQL Server 库?

我查看了ICAL.net,但似乎没有太多关于它的文档,或者我将如何将它用于上述目的。

有人对 ICAL.net 有任何经验吗?

【问题讨论】:

  • 您将不得不拆分字符串并提取不同的部分,在您的开始和结束(递归 cte)之间建立一个日期表,或者日期维度会很好。然后使用一堆案例语句来识别日期、界面、星期几、月末、每月第一个星期四等的所有组合......这不是一项轻松的任务,而是可行的。

标签: jquery sql sql-server icalendar rrule


【解决方案1】:

如果您有很多重复事件,那么数据库和应用程序需要做大量工作。在我编写的日历应用程序中,我在创建事件时扩展了规则,并将每个重复事件放在单独的行中。我添加了一个唯一的 id 字段(在 icalendar 规范中的 UID,与 id 字段分开),因此如果需要,我可以在查询中将重复事件分组在一起(重复系列中的每个事件都具有相同的唯一 ID)。然后,使用标准查询搜索日期就很容易了。如果它们在规则中,它还可以更轻松地避免包含异常,因为它们在数据库中不会有一行。

【讨论】:

  • 你能提供一个你的数据库模式的例子吗?每个重复事件不会使数据库膨胀吗?假设有一个没有结束日期但无限重复的事件 - 这将很快耗尽所有数据库存储空间。参考以下文档:github.com/bmoeskau/Extensible/blob/master/…
  • 创建活动时,我使用的日期范围将重复日期限制为一个时间段,例如 1 年前到 3 年后,然后具有扩展/删除重复日期的功能随着时间的流逝。不是最好的,但查询很快。这里没有足够的空间来显示表格架构,但您可以下载具有此功能的 Zap Calendar Lite 的免费版本并查看代码(需要 Joomla)zcontent.net/products/zap-calendar-lite
【解决方案2】:

有人对 ICAL.net 有任何经验吗?

不是,但我是php-rrule 的作者,我认为我的回答也适用于您的情况。

首先让我们这样说,除非您有一组非常有限的规则,并且您知道,例如,没有事件是无限的,或者重复超过 X 次或其他任何事情,否则在存储不会发生之前扩展规则上班。

据我所知,你不能只用SQL来做,你必须分两步来做。

  1. 查询dt_start是或在2016-10-10之前和dt_end是或在2016-10-10之后的所有事件。
  2. 丢弃所有在 2016 年 10 月 10 日不会发生的事件,因为它们的规则(例如BYDAY)。为此,您将需要一个库(我猜是 ICAL.net),它可以快速计算来自 rrule 字段的出现次数。

我建议您在完成此操作后缓存结果,因此对于任何后续查询,您将能够读取 2016-10-10 的缓存,而不是再次进行计算。每当添加、更新或删除包含 dt_startdt_end 之间的 2016-10-10 的事件时,您必须注意使缓存无效。

【讨论】:

    猜你喜欢
    • 2011-01-08
    • 1970-01-01
    • 2021-03-04
    • 2012-07-24
    • 2017-09-05
    • 2011-09-26
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多