1

我正在做这个项目,我需要创建一个大的 HTML 表格,其中每个表格行是 15 分钟间隔,每个表格列是一天。目标是在房间可用和不可用时向用户显示想要预订房间的用户。所有网页都是打印出正确 HTML 的 PL/SQL 包。

某个房间的桌子示例:

在此处输入图像描述

(不要介意不同的颜色)

所有房间定义都存储在一个包含开始日期、结束日期、开始时间、结束时间和星期几的 Oracle 数据库中。例如,一个定义可以是:

(07-31-2013 - 07-31-2014, 00:00 - 23:59, Mondays,Tuesdays and Fridays)

我担心的是,要构建我的 html 表的每个正方形,我需要进行查询以检查是否定义了该特定时期。(例如,如果用户想查看一个房间从 10:00 到 14:00 的整周,则每隔 15 分钟将进行 112 次查询来构建表)更不用说用户最多可以查看 4 周并且从任何时间间隔(可能是从 00:00 到 23:59)。另一个问题是我需要对房间定义进行检查,但我还必须多次检查以查看该间隔是否被预订占用......所以只进行 224 次查询才能看到一周。

我的解决方案是获取所有可能影响用户希望查看的时间段的房间定义和预订,并将它们放入一个集合中(1 个集合用于定义,1 个用于预订)。之后,我在不进行查询的情况下对这些集合运行所有测试。我的主过程调用一个函数,将两个集合作为参数发送,函数返回真或假。

我想知道 oracle 是否可以处理这么多小请求,或者我是否对这些集合做了正确的事情?

我读了很多帖子说集合对记忆不好,我担心通过函数参数传递它们可能也无济于事......尽管它可能不适用于我的情况,考虑到集合可能永远不会超过 1-5其中的记录。

我检查它是否可用的查询将是这样的:

SELECT DISTINCT 'Y' 
FROM room_defenition
WHERE
START_DATE <= USER_DATE AND 
END_DATE >= USER_DATE AND
--F_TO_DAY converts the date to the coresponding code
REGEXP_INSTR(MON||TUE||WED||THU||FRI||SAT||SUN,F_TO_DAY(USER_DATE)) <> 0 AND
START_TIME <= USER_START_TIME AND 
END_TIME >= USER_END_TIME;

USER_DATE 将是我正在测试的当前列,而 USER_START_TIME 和 USER_END_TIME 将是当前间隔的两个边界。(例如 07-31-2013 - 10:00 - 10:15)。

我在 where 子句中还有 2 个子查询来检查用户是否被允许在这个房间进行预订......

4

1 回答 1

3

做这种事情的一种解决方案是创建称为维度的表。您的数组有两个维度,因此您将创建两个表,QUARTERS例如,一个称为一个,每天每 15 分钟有一行(所以 96 行)

id    timestart   timeend
-----------------
1      00:00  00:15
2      00:15  00:30
...

一个电话CALENDAR可以保留全年的天数(或接下来的 10 年,没关系)

id    dateofday
---------------
1     01/01/2013
2     02/01/2013
...

很容易构建一个查询,为数组的每个单元格提供一行,无论是否有可用房间。

select timestart, timeend, dateofday
from quarters cross join calendar -- a legitimate use for cross join
where timestart >= user_time_start and
      timeend   <= user_time_end and
      dateofday between user_date_start and user_date_end 
order by quarters.id, calendar.id

结果按数组的行排序,然后按列排序。因此,您可以一次读取一行查询的结果并即时构建您的数组(无需收集或复杂的算法)

现在您只需要添加一个子查询来告诉您房间是否可用,例如:

select timestart, timeend, dateofday,
    (*subquery on room_definition *) available
    from quarters cross join calendar -- a legitimate use for cross join
    where timestart >= user_time_start and
          timeend   <= user_time_end and
          dateofday between user_date_start and user_date_end 
    order by quarters.id, calendar.id
于 2013-07-31T13:14:11.527 回答