Przejście z puli na pokoje takie proste nie jest, bo w puli program przypisuje w tle pokój, ale później ignoruje tę informację. Jeśli przełączymy parametr, to okaże się, że duża część pokoi ma overbooking, ale też będziemy mieli wolne pokoje tam, gdzie pula nie miała już dostępności - po prostu rezerwacje będą się na siebie nakładać. Aktualizacja obłożenia sobie z tym nie poradzi skutecznie.
W złączniku trzy skrypty:
- zakładający strukturę tablicy dat (CONST_CZAS_table.sql)
- wypełniający tablicę dat danymi (CONST_CZAS_regen.sql)
- przypisujący rezerwacje do pokoju (PulaNaPokoje.sql)
Pierwsze dwa są pomocnicze - tablica wykorzystywana jest w rozrzucaniu rezerwacji do pokoi, ale przydaje się w raportowaniu (mamy skąd wyciągnąć rekord dla dni bez zdarzeń, np. liczba rezerwacji na dzień, w którym hotel będzie pusty).
Trzeci skrypt buforuje informację o pokoju w rezerwacji, wrzuca rezerwacja gwarantowane do ich pokoi, a całą resztę rezerwacji rozpisuje kolejno do dostępnych pokoi. Skrypt utrzymuje typ pokoju, w razie overbokingu może przypisać rezerwację w pokoju wirtualnym, ale pokój musi być pokojem gościnnym. Pokoje z remontami blokującymi pokój również są traktowane jako zajęte przy wyszukiwaniu pokoju docelowego.
Sugerowana kolejność wykonania:
- założyć tablicę CONST_CZAS
- wypełnić tablice CONST_CZAS
- zmienić parametr PokazPrzydzieloniePokoIWgPuli na 0
- wykonać kopię bazy danych
- wykonać przypisanie pokoi
- sprawdzić rezerwacje bez pokoi (to będą overbookingi; jeśli wszystko poszło OK, to ostatnie dwa zapytania w skrypcie nie zwrócą żadnych rekordów)
- wykonać aktualizację obłożenia
Tablica CONST_CZAS
Kod: Zaznacz cały
CREATE GENERATOR SEQ_CONST_CZAS_ID;
CREATE TABLE CONST_CZAS (
CZAS_ID INTEGER NOT NULL,
DATACZAS DATE,
ROK INTEGER,
DZIENMIESIACA INTEGER,
TYDZIENROKU INTEGER,
MIESIACROKU INTEGER,
KWARTALROKU VARCHAR(2),
DZIENTYG INTEGER,
DZIENTYG_NAZWA VARCHAR(3),
MIESIACROKU_NAZWA COMPUTED BY (IIF(MIESIACROKU>9,MIESIACROKU,'0'||MIESIACROKU))
);
ALTER TABLE CONST_CZAS ADD CONSTRAINT PK_CONST_CZAS PRIMARY KEY (CZAS_ID);
CREATE UNIQUE INDEX CONST_CZAS_IDX1 ON CONST_CZAS (DATACZAS);
SET TERM ^ ;
CREATE OR ALTER TRIGGER CONST_CZAS_BI FOR CONST_CZAS
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.czas_id is null) then
new.czas_id = gen_id(SEQ_CONST_CZAS_id,1);
new.rok = extract(year from new.dataczas);
new.dzienmiesiaca = extract(day from new.dataczas);
new.tydzienroku = extract(week from new.dataczas);
new.miesiacroku = extract(month from new.dataczas);
new.kwartalroku = case when (extract(month from new.dataczas)) <= 3 then 'Q1'
when (extract(month from new.dataczas)) <= 6 then 'Q2'
when (extract(month from new.dataczas)) <= 9 then 'Q3'
when (extract(month from new.dataczas)) <= 12 then 'Q4'
end;
new.dzientyg = extract(weekday from new.dataczas -1) + 1;
new.dzientyg_nazwa = case new.dzientyg when 1 then 'Pon'
when 2 then 'Wto'
when 3 then 'Sro'
when 4 then 'Czw'
when 5 then 'Pia'
when 6 then 'Sob'
when 7 then 'Nie'
end;
end
^
SET TERM ; ^
Kod: Zaznacz cały
set term ^;
CREATE OR ALTER PROCEDURE REBLD_CONST_CZAS
AS
DECLARE VARIABLE DATA DATE;
BEGIN
DELETE FROM CONST_CZAS;
EXECUTE STATEMENT 'ALTER SEQUENCE SEQ_CONST_CZAS_ID RESTART WITH 0';
DATA = '1899-12-31';
WHILE (:DATA < '2051-01-01') DO
BEGIN
INSERT INTO CONST_CZAS (DATACZAS) VALUES (:DATA);
DATA = DATA + 1;
END
EXECUTE STATEMENT 'SET STATISTICS INDEX PK_CONST_CZAS;';
EXECUTE STATEMENT 'SET STATISTICS INDEX CONST_CZAS_IDX1;';
END
^
set term ;^
commit;
execute procedure rebld_const_czas;
commit;
Kod: Zaznacz cały
--TYMCZOWE POLE Z INFORMACJA O ZAREZERWOWANYM POKOJU
ALTER TABLE REZERWACJA ADD AJP_POKOJ_ID INT;
COMMIT;
UPDATE REZERWACJA SET AJP_POKOJ_ID = POKOJ_ID;
UPDATE REZERWACJA SET POKOJ_ID = -1 WHERE REZERWACJA_AKTYWNA = 1;
DELETE FROM OBLOZENIE; DELETE FROM OBLOZENIETYPU;
--REZERWACJE GWARANTOWANE
UPDATE REZERWACJA SET POKOJ_ID = AJP_POKOJ_ID WHERE REZERWACJA_POTWIERDZONA = 2 OR REZERWACJA_POTWIERDZONA = 3;
--PROCEDURA
set term ^;
create or alter procedure ajp_freeroom (
roomType int not null,
startDate date not null)
returns (roomId int)
as
begin
select p.pokoj_id from pokoj p, const_czas cc
where cc.dataczas = :startDate
and p.pokojtyp_id = :roomType
and not exists (select rezerwacja_id from rezerwacja re where re.rezerwacja_aktywna = 1 and re.pokoj_id = p.pokoj_id and re.rezerwacja_data_od <= :startDate and re.rezerwacja_data_do > :startDate)
and not exists (select meldunek_id from meldunek me where me.pokoj_id = p.pokoj_id and me.meldunek_data_od <= :startDate and me.meldunek_data_do > :startDate)
and not exists (select zlecenie_id from zlecenie z where z.pokoj_id = p.pokoj_id and z.zlecenie_data_od <= :startDate and z.zlecenie_data_do > :startDate and z.zlecenie_wylaczenie = 1)
and p.pokoj_status = 0
order by p.pokoj_wirtualny, p.pokoj_id
rows 1
into :roomId;
if (roomId is null) then roomId = -3;
suspend;
end^
create or alter procedure ajp_pula_na_pokoje as
begin
UPDATE REZERWACJA RE SET RE.POKOJ_ID = (select roomid from ajp_freeroom(re.pokojtyp_id, re.rezerwacja_data_od))
where re.pokoj_id < 0
order by rezerwacja_data_od, rezerwacja_id;
end
^
set term ;^
--KONIEC PROCEDURY
execute procedure ajp_pula_na_pokoje;
--KASUJE TYMCZASOWE POLE
ALTER TABLE REZERWACJA DROP AJP_POKOJ_ID;
COMMIT;
--TEST
select count(*) from rezerwacja where pokoj_id < 0;
select cc.dataczas, p.pokoj_id, count(re.rezerwacja_id) from const_czas cc, pokoj p, rezerwacja re where cc.dataczas <= re.rezerwacja_data_od and cc.dataczas > re.rezerwacja_data_do and p.pokoj_id = re.pokoj_id and re.rezerwacja_aktywna = 1 group by 1,2 having count (re.rezerwacja_id) > 1;