使用C#在SQL表中创建“月度时间表/计划日历”

时间:2016-05-02 08:00:58

标签: c# sql-server

对于上下文,我正在为兽医诊所创建一个数据库。

我在Microsoft SQL Server Management Studio 2014中有一个SQL表,其关系模型(模式)如下所示: ScheduleSlot(slotID,room,date,startTime,endTime,appointment_id,staff_id)我想喜欢部分预先填写。

  • appointment_id和staff_id是foeign_keys,为了这个“空日历”
  • 可以而且应该为空
  • 通风诊所每周开放6天,周日休息。
  • 每次约会都是半小时。
  • 营业时间为上午8:00至下午5:00。

我想创建一个日记结构,让您每天都可以定义兽医可能使用的插槽。

例如,我希望在2016年5月的所有26个星期日内制作类似的东西:

slotId  date        startTime   endTime room    appointment_id  staff_id
1       5/2/2016    8:00        8:30    1       null            null
2       5/2/2016    8:00        8:30    2       null            null
3       5/2/2016    8:00        8:30    3       null            null
4       5/2/2016    8:00        8:30    4       null            null
5       5/2/2016    8:30        9:00    1       null            null
6       5/2/2016    8:30        9:00    2       null            null
7       5/2/2016    8:30        9:00    3       null            null
8       5/2/2016    8:30        9:00    4       null            null
9       5/2/2016    9:00        9:30    1       null            null
10      5/2/2016    9:00        9:30    2       null            null
11      5/2/2016    9:00        9:30    3       null            null
12      5/2/2016    9:30        9:30    4       null            null
...     ...         ...         ...     ...     ...             ...

作为参考,任何一个月每天应该有72个(18个间隔×4个房间的正面)插槽,而2016年5月的时段应该是1872个插槽(72 x 26)。

我可能的解决方案a使用modulo(循环)来检查i%7 == 0并跳过它? - for循环可以作为第一个日期传递参数,并一直工作到月末。

3 个答案:

答案 0 :(得分:3)

不要这样做

只需要一个约会表来存储约会时间。

SQL通常不应对业务规则负责。

在将其交给数据库进行存储之前,在中间层或处理业务逻辑的任何地方执行此操作。

如果在任何一天,您只有2个约会,那么当天应该只有2行。不是一堆包含所有可用时隙和NULL的行。这是浪费空间和不必要的开销。

如果您想从数据库端强制完整性,以确保从您的数据访问层(例如工作时间以外的约会或重叠约会)没有任何无效,您可以使用触发器并检查约束条件检查有效逻辑,或通过执行相同操作的存储过程发送所有内容。

答案 1 :(得分:0)

正如@Patrick所说不要这样做,因为过了一段时间你会有很多垃圾数据你应该删除它。这种垃圾会在报告时遇到麻烦。< / p>

所以,如果我是你,我会创建一个表来安排像房间,持续时间,开始时间,结束时间...... 当我想插入新约会时,我尝试按计划规则和最后一次约会创建新约会。

例如,最后一次约会是在2016年5月2日13:00在#1房间, 在计划表中我知道会议的持续时间是一半和一小时,

所以我在2016年5月2日14:30开始为#1房间创建新约会

此外,您可以找到许多解决方案,以最佳方式执行此操作。

答案 2 :(得分:0)

如果您确实想要使用所需的值预填充表格,可以使用此

DECLARE @desiredMonth int = 5;
DECLARE @desiredYear int = 2016;

SELECT StartDate, 
DATEADD(minute, 30, StartDate) AS EndDate, 
rooms AS Room 
FROM
(
    SELECT 
    /* Construct StartDate */
    dateadd(minute, minutes, dateadd(hour, hours, dateadd(day, days - 1, dateadd(month, @desiredMonth - 1, dateadd(year, @desiredYear - 1900, 0))))) AS StartDate,
    minutes,
    rooms
    FROM (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19), (20), (21), (22), (23), (24), (25), (26), (27), (28), (29), (30), (31)) AS W(days)
    CROSS JOIN (VALUES (8), (9), (10), (12), (12), (13), (14), (15), (16)) AS X(hours)
    CROSS JOIN (VALUES (00), (30)) AS Y(minutes)
    CROSS JOIN (VALUES (1), (2), (3), (4)) AS Z(rooms)
    /* Check, that only days are included for desired month */
    WHERE DATEPART(m, dateadd(hour, hours, dateadd(day, days - 1, dateadd(month, @desiredMonth - 1, dateadd(year, @desiredYear - 1900, 0))))) = @desiredMonth
) AS SubQuery01

但我同意其他意见,通常你不应该这样做。也许在视图中使用会更好?