繁体   English   中英

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

[英]Using C# to create a “monthly timetable/schedule calender” in a SQL table

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

我在Microsoft SQL Server Management Studio 2014中有一个带有关系模型(schema)的SQL表,如下所示:我想部分预先填充的ScheduleSlot(slloottIdD̲,房间,日期,startTime,endTime,约会ID,staff_id)

  • 约会ID和职员ID是foeign_key,为此“空日历”的目的可以并且应该为null
  • 发泄诊所每周仅开放6天,周日关闭。
  • 每个可能的约会都是半小时。
  • 营业时间为8:00 am-5:00 pm。

我想创建一个日记结构,该日记结构允许您每天定义兽医可能可用的位置。

例如,我想为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
...     ...         ...         ...     ...     ...             ...

作为参考,任何月份,以及2016年5月每月应有72个(18个间隔x 4个房间posiblites)插槽,约1872个插槽(72 x 26)。


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

不要这样做

只是有一个约会表,用于存储安排约会的时间。

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

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

如果在给定的一天中您只有2个约会,那么该天您应该只有2行。 没有一堆具有所有可用时隙和NULL的行。 那是浪费空间和不必要的开销。

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

就像@Patrick所说的那样不要这样做 ,因为过一会儿您应该删除大量垃圾数据后,这种垃圾将给报告带来麻烦。

因此,如果我是您,我将创建一个用于安排时间的表格,例如房间,持续时间,开始时间,结束时间...。当我想插入新约会时,我尝试通过时间表规则和最后一次约会。

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

所以我在5/2/2016 14:30为#1房间创建了新约会

您也可以找到许多解决方案,以最好的方式做到这一点。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM