1

私はこのプロジェクトに取り組んでおり、各テーブル行が 15 分間隔で、すべてのテーブル列が 1 日である大きな HTML テーブルを作成する必要があります。目標は、部屋が空いている場合とそうでない場合に部屋を予約したいユーザーを示すことです。すべての Web ページは、適切な HTML を出力する PL/SQL パッケージです。

特定の部屋のテーブルの例:

ここに画像の説明を入力

(色違いは気にしないでください)

すべての部屋の定義は、開始日、終了日、開始時間、終了時間、および曜日を含む Oracle データベースに保存されます。たとえば、定義は次のようになります:

(07-31-2013 - 07-31-2014、00:00 - 23:59、月曜日、火曜日、金曜日)

私の懸念は、HTML テーブルのすべての正方形を作成するには、その特定の期間が定義されているかどうかを確認するクエリを作成する必要があることです。(たとえば、ユーザーが部屋の 10:00 から 14:00 までの 1 週間全体を表示したい場合、15 分間隔でテーブルを作成するために 112 のクエリが実行されます) ユーザーが最大 4 週間表示できることは言うまでもありませんおよび任意の時間間隔から (00:00 から 23:59 まで)。もう1つの問題は、部屋の定義を確認する必要があることですが、その間隔が予約に使用されているかどうかを確認するために何度も別の確認を行う必要があることです.

私の解決策は、ユーザーが見たい期間に影響を与える可能性のあるすべての部屋の定義と予約を取得し、それらをコレクションに入れることでした (定義用に 1 つのコレクション、予約用に 1 つのコレクション)。その後、クエリを実行せずに、これらのコレクションに対してすべてのテストを実行します。私のメイン プロシージャは、両方のコレクションをパラメーターとして送信する関数を呼び出し、関数は true または false を返します。

オラクルがその多くの小さなリクエストを処理できるかどうか、またはコレクションで正しいことをしたかどうか疑問に思っていましたか?

コレクションがメモリに悪いという多くの投稿を読みましたが、関数パラメーターを介してそれらを渡すことも役に立たないのではないかと心配しています...コレクションがおそらく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 は現在の間隔の 2 つの境界になります。(例: 2013 年 7 月 31 日 - 10:00 - 10:15)。

また、ユーザーがこの部屋の予約を許可されているかどうかを確認するために、where 句に 2 つのサブクエリがあります...

4

1 に答える 1

3

このようなことを行うための 1 つの解決策は、ディメンションと呼ばれるテーブルを作成することです。配列には 2 つの次元があるためQUARTERS、たとえば 1 日 15 分ごとに 1 行 (96 行) を持つ2 つのテーブルを作成します。

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

そして、1CALENDAR年間 (または、次の 10 年間は関係ありません) の日数を保持するものです。

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

利用可能な部屋があるかどうかに関係なく、配列の各セルに対して正確に 1 つの行を与えるクエリを作成するのは簡単です。

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

結果は、配列の行、次に列で並べ替えられます。そのため、一度に 1 行ずつクエリの結果を読み取り、その場で配列を作成できます (コレクションや複雑なアルゴリズムは必要ありません)。

次に、次のような部屋が利用可能かどうかを示すサブクエリを追加する必要があります。

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 に答える