Paulina Gogół s241906 BAZA DANYCH SIECI HOTELI Baza jest częścią systemu zarządzającego pewną siecią hoteli. Składa się z tabeli powiązanych ze sobą różnymi relacjami. Służy ona lepszemu zorganizowaniu pracy hoteli. Zawiera informacje niezbędne do łatwej i szybkiej współpracy pomiędzy hotelami i ich pracownikami. Baza posiada wiele zastosowań. Możemy uzyskać z niej informacje na temat zorganizowania i umiejscowienia hoteli, klientów korzystających z usług hoteli, osób mieszkających aktualnie w hotelach oraz tych którzy mieszkali w dowolnym czasie. Składa się z 8 tabel Hotele (zawierająca informacje dotyczące nazwy hotelu, miasta, w jakim się znajduje, ilości pokoi oraz standardu) Klienci (zawierająca dane klientów mieszkających w hotelach) Pokoje (określająca jakie pokoje w jakiej cenie znajdują się w hotelach) Rodzaje pokoi (tabela jedno atrybutowa służąca do przechowywania informacji na temat rodzaju pokoi) Rezerwacje (tabela zawierająca informacje o dokonanych rezerwacjach) Parking (przydzielająca miejsca parkingowe klientom) Mieszkańcy (przechowuje informacje na temat osób aktualnie mieszkających w hotelu) Historia_pobytów (tabela zawierająca wszystkie informacje o pobytach w hotelach)
DIAGRAM ENCJI BAZY DANYCH
Funkcjonalności bazy danych Baza pozwala dodawać nowych klientów do bazy, wyszukiwać wolne pokoje w danym hotelu, rezerwować pokoje, apartamenty oraz miejsca parkingowe. Zawiera informacje na temat osób przebywających aktualnie w hotelach. Korzystając z tabeli historii możemy także uzyskać informacje na temat pobytu wybranego klienta w dowolnym czasie, możemy także określić kto przebywał w danym hotelu w danym okresie. Możemy wyszukiwać dane do statystyk np. który hotel jest najchętniej odwiedzany, który hotel w którym miesiącu miał najwięcej mieszkańców, jaki rodzaj pokoju lub numer pokoju był najczęściej wybierany i wiele innych. Baza posiada następujące ograniczenia: Numer dowodu musi mieć określoną formę W atrybucie płatność możemy wpisać tylko wartości: karta lub gotówka Status pokoju musi być albo wolny albo zajęty Pokój musi mieć zmieniony status jeśli pojawia się w tabeli mieszkańcy lub zostaje stamtąd usunięty (tzn. gdy ktoś w nim zamieszka lub wyprowadzi się) Data zameldowania musi być mniejsza od daty wymeldowania Podczas pracy z bazą możemy korzystać z funkcji Aktualizuj_mieszkancow która usuwa z tabeli mieszkancy i wpisuje do tabeli historia_pobytow dane osób już wymeldowanych z hotelu Płatność która po podaniu numeru identyfikacyjnego klienta wyświetla ile dany klient ma zapłacić
KOD TWORZENIE TABEL i WIĘZÓW DROP TABLE hotele CASCADE; CREATE TABLE hotele ( nr_hotelu SERIAL PRIMARY KEY, nazwa_hotelu VARCHAR (20) UNIQUE, miasto VARCHAR (20) NOT NULL, standard VARCHAR(5) NOT NULL); DROP TABLE klienci CASCADE; CREATE TABLE klienci ( nr_id_klienta SERIAL PRIMARY KEY, nazwisko VARCHAR(30) NOT NULL, imie VARCHAR(30) NOT NULL, nr_dowodu VARCHAR(9) NOT NULL UNIQUE CHECK (nr_dowodu ~ '^[A-Z]{3}[0-9]{6}$') ); DROP TABLE rodzaje_pokoi CASCADE; CREATE TABLE rodzaje_pokoi (rodzaj_pokoju VARCHAR(15) PRIMARY KEY); DROP TABLE pokoje CASCADE; CREATE TABLE pokoje ( nr_hotelu INT REFERENCES hotele(nr_hotelu) ON UPDATE CASCADE ON DELETE CASCADE, nr_pokoju INT NOT NULL, rodzaj_pokoju VARCHAR(10) REFERENCES rodzaje_pokoi(rodzaj_pokoju) ON UPDATE CASCADE ON DELETE CASCADE, cena INT NOT NULL, status VARCHAR(10) CHECK (status IN ('wolny','zajety')) DEFAULT 'wolny'); ALTER TABLE pokoje ADD PRIMARY KEY (nr_hotelu,nr_pokoju); DROP TABLE rezerwacje CASCADE; CREATE TABLE rezerwacje ( nr_rezerwacji SERIAL PRIMARY KEY, nazwa_hotelu VARCHAR(20) REFERENCES hotele(nazwa_hotelu) ON UPDATE CASCADE ON DELETE RESTRICT, nr_id_klienta INT REFERENCES klienci(nr_id_klienta) ON UPDATE CASCADE ON DELETE RESTRICT, rodzaj_pokoju VARCHAR(15) REFERENCES rodzaje_pokoi(rodzaj_pokoju) ON UPDATE CASCADE ON DELETE CASCADE, data_przyjazdu DATE NOT NULL, data_odjazdu DATE, czy_parking BOOLEAN DEFAULT FALSE, platnosc VARCHAR(10) CHECK (platnosc IN ('gotowka', 'karta')));
DROP TABLE mieszkancy CASCADE; CREATE TABLE mieszkancy ( id_mieszkanca SERIAL PRIMARY KEY, nr_rezerwacji INT REFERENCES rezerwacje (nr_rezerwacji) ON UPDATE CASCADE ON DELETE RESTRICT, nr_id_klienta INT REFERENCES klienci(nr_id_klienta) ON UPDATE CASCADE ON DELETE RESTRICT, nr_hotelu INT REFERENCES hotele(nr_hotelu) ON UPDATE CASCADE ON DELETE RESTRICT, nr_pokoju INT, data_zameld DATE NOT NULL, data_wymeld DATE); DROP TABLE parking CASCADE; CREATE TABLE parking ( id_mieszkanca INT REFERENCES mieszkancy(id_mieszkanca) ON UPDATE CASCADE ON DELETE CASCADE, miejsce INT); DROP table historia_pobytow CASCADE; CREATE TABLE historia_pobytow ( id_mieszkanca INT, nr_id_klienta INT, nr_hotelu INT, nr_pokoju INT, data_zameld DATE, data_wymeld DATE); WIDOKI, FUNKCJE i WYZWALACZE CREATE VIEW pokoje_w_hotelu AS SELECT p.nr_hotelu, h.nazwa_hotelu, p.nr_pokoju, p.rodzaj_pokoju, p.status FROM pokoje p, hotele h WHERE p.nr_hotelu=h.nr_hotelu ORDER BY nr_hotelu, nr_pokoju; CREATE VIEW wolne_pokoje AS SELECT nr_hotelu, nr_pokoju FROM pokoje WHERE status='wolny'; CREATE OR REPLACE FUNCTION zmien_status_pokoju() RETURNS TRIGGER AS $$ BEGIN UPDATE pokoje SET status='zajety' WHERE (nr_hotelu=new.nr_hotelu AND nr_pokoju=new.nr_pokoju); RETURN NEW; END; $$ LANGUAGE 'plpgsql';
CREATE TRIGGER zmien_status_pokoju_trigger BEFORE INSERT OR UPDATE ON mieszkancy FOR EACH ROW EXECUTE PROCEDURE zmien_status_pokoju(); CREATE OR REPLACE FUNCTION zmien_status_pokoju2() RETURNS TRIGGER AS $$ BEGIN UPDATE pokoje SET status='wolny' WHERE (nr_hotelu=old.nr_hotelu AND nr_pokoju=old.nr_pokoju); RETURN NEW; END; $$ LANGUAGE 'plpgsql'; CREATE TRIGGER zmien_status_pokoju2_trigger AFTER DELETE ON mieszkancy FOR EACH ROW EXECUTE PROCEDURE zmien_status_pokoju2(); CREATE OR REPLACE FUNCTION sprawdz_daty() RETURNS TRIGGER AS $$ BEGIN IF (NEW.data_wymeld IS NOT NULL) AND (NEW.data_zameld>NEW.data_wymeld) THEN RAISE EXCEPTION 'Podano zle daty' ; END IF; RETURN NEW; END; $$ LANGUAGE 'plpgsql'; DROP TRIGGER sprawdz_daty_trigger ON mieszkancy CASCADE; CREATE TRIGGER sprawdz_daty_trigger BEFORE INSERT OR UPDATE ON mieszkancy FOR EACH ROW EXECUTE PROCEDURE sprawdz_daty(); CREATE OR REPLACE FUNCTION aktualizuj_mieszkancow () RETURNS TEXT AS $$ DECLARE w RECORD; ilosc INT; BEGIN ilosc=0; FOR w IN SELECT id_mieszkanca, nr_id_klienta, nr_hotelu, nr_pokoju, data_zameld, data_wymeld FROM mieszkancy WHERE data_wymeld<current_date LOOP INSERT INTO historia_pobytow VALUES(w.id_mieszkanca,w.nr_id_klienta, w.nr_hotelu, w.nr_pokoju, w.data_zameld, w.data_wymeld); DELETE FROM mieszkancy WHERE id_mieszkanca=w.id_mieszkanca; ilosc=ilosc+1; END LOOP; RETURN 'Przeniesiono' ' ' ilosc ' ' 'wpisow do tabeli historia_pobytow'; END; $$ LANGUAGE 'plpgsql'; CREATE OR REPLACE FUNCTION platnosc (nr_id_klienta_arg INT) RETURNS TEXT AS $$ DECLARE
w RECORD; c INT; do_zaplaty INT; BEGIN SELECT INTO w data_zameld, data_wymeld, nr_hotelu, nr_pokoju FROM mieszkancy WHERE nr_id_klienta=nr_id_klienta_arg; SELECT cena INTO c FROM pokoje WHERE nr_hotelu=w.nr_hotelu AND nr_pokoju=w.nr_pokoju; do_zaplaty=(w.data_wymeld-w.data_zameld)*c; RETURN 'Do zaplaty: ' do_zaplaty ' ' 'zl'; END; $$ LANGUAGE 'plpgsql'; DANE INSERT INTO hotele (nazwa_hotelu, miasto, standard) VALUES ('Mercury', 'Wroclaw', '***'), ('Venus', 'Warszawa', '****'), ('Jupiter', 'Poznan', '***'), ('Amber', 'Zakopane', '****'), ('Saturn', 'Krakow', '***'); INSERT INTO klienci (nazwisko, imie, nr_dowodu) VALUES ('Kowalski', 'Jan', 'ARW371561'), ('Wisniewski', 'Tadeusz', 'ASZ567820'), ('Cebulska', 'Malgorzata', 'KRM341290'), ('Kwiatkowska', 'Irena', 'KLN654312'), ('Rogalski', 'Miroslaw', 'AGS341523'), ('Markowski', 'Zygmunt', 'TRS789012'); ('Kapuscinski','Marek', 'AWR346780'), ('Bieganska', 'Jolanta', 'WES189023'), ('Nowak', 'Kazimierz', 'TWA654738'), ('Mazurek','Klaudia', 'PLD109865'); INSERT INTO rodzaje_pokoi (rodzaj_pokoju) VALUES ('1-osobowy'), ('2-osobowy'), ('3-osobowy'), ('Apartament'); INSERT INTO pokoje (nr_hotelu, rodzaj_pokoju, cena, nr_pokoju) VALUES (1,'1-osobowy', 250,1),(2,'1-osobowy', 250,1),(3,'1-osobowy', 250,1), (4,'1-osobowy', 250,1),(5,'1-osobowy', 250,1),(1,'1-osobowy', 250,2),
(2,'1-osobowy', 250,2),(3,'1-osobowy', 250,2),(4,'1-osobowy', 250,2), (5,'1-osobowy', 250,2), (1,'2-osobowy', 400,3),(2,'2-osobowy', 400,3), (3,'2-osobowy', 400,3),(4,'2-osobowy', 400,3), (5,'2-osobowy', 400,3), (1,'2-osobowy', 400,4),(2,'2-osobowy', 400,4),(3,'2-osobowy', 400,4), (4,'2-osobowy', 400,4),(5,'2-osobowy', 400,4),(1,'2-osobowy', 400,5), (2,'2-osobowy', 400,5),(3,'2-osobowy', 400,5),(4,'2-osobowy', 400,5), (5,'2-osobowy', 400,5),(1,'3-osobowy', 500,6), (2,'3-osobowy', 500,6), (3,'3-osobowy', 500,6),(4,'3-osobowy', 500,6),(5,'3-osobowy', 500,6), (1,'3-osobowy', 500,7),(2,'3-osobowy', 500,7),(3,'3-osobowy', 500,7), (4,'3-osobowy', 500,7),(5,'3-osobowy', 500,7),(1,'1-osobowy', 250,8), (1,'1-osobowy', 250,9),(2,'1-osobowy', 250,8),(3,'1-osobowy', 250,8), (4,'1-osobowy', 250,8),(1,'Apartament', 1000,10), (2,'Apartament',1000,9), (3,'Apartament', 1000,9),(4,'Apartament', 1000,9),(5,'Apartament', 1000,8), (1,'Apartament', 1000,11),(2,'Apartament', 1000,10),(3,'Apartament', 1000,10), (4,'Apartament', 1000,10),(5,'Apartament', 1000,9), (1,'Apartament', 1000,12),(2,'Apartament', 1000,11),(3,'Apartament', 1000,11),(4,'Apartament', 1000,11),(5,'Apartament', 1000,10); INSERT INTO rezerwacje (nazwa_hotelu, nr_id_klienta,rodzaj_pokoju, data_przyjazdu,data_odjazdu, czy_parking, platnosc) VALUES ('Mercury',3, '1-osobowy', '2014-01-22', '2014-01-29', FALSE, 'karta'), ('Saturn', 5, 'Apartament', '2013-12-14', '2013-12-31', TRUE, 'karta'), ('Mercury',4, 'Apartament', '2014-02-17', '2014-03-01', FALSE, 'gotowka'), ('Venus', 10, '2-osobowy', '2014-01-02', '2014-01-05', TRUE, 'gotowka'), ('Amber', 7, '3-osobowy', '2014-04-19', '2014-04-29', FALSE, 'karta'), ('Amber', 6, '3-osobowy', '2014-05-19', '2014-05-29', FALSE, 'karta'), ('Jupiter', 6, '1-osobowy', '2014-02-10', '2014-02-11', TRUE, 'gotowka'), ('Jupiter', 5, '1-osobowy', '2014-01-10', '2014-01-30', TRUE, 'karta'), ('Jupiter', 1, '2-osobowy', '2014-02-10', '2014-02-15', TRUE, 'gotowka'), ('Saturn', 2, 'Apartament', '2014-03-12', '2014-03-17', FALSE, 'karta'), ('Saturn', 3, 'Apartament', '2014-03-12', '2014-03-17', FALSE, 'karta'), ('Saturn', 9, '1-osobowy', '2014-02-12', '2014-02-21', FALSE, 'karta'), ('Venus', 8, '3-osobowy', '2013-11-15', '2013-11-30', TRUE, 'karta'); INSERT INTO mieszkancy (nr_rezerwacji, nr_id_klienta,nr_hotelu, nr_pokoju, data_zameld, data_wymeld) VALUES (2, 5, 5,1, '2013-12-14', '2013-12-31'), (4, 10,2,4, '2014-01-02', '2014-01-05'), (13, 8, 2,6, '2013-11-15', '2013-11-30'); INSERT INTO mieszkancy (nr_rezerwacji, nr_id_klienta,nr_hotelu, nr_pokoju, data_zameld) VALUES (1,3,1,1,'2014-01-22'), (8,5, 3,1, '2014-01-10'); INSERT INTO parking VALUES (2,10);
Rejestracja nowego klienta w bazie Dokonanie rezerwacji
Dodawanie nowego mieszkańca Przykładowe polecenia a) Wypisanie klientów, którzy mieszkają w hotelu Mercury SELECT m.nr_id_klienta FROM mieszkancy m, hotele h WHERE m.nr_hotelu=h.nr_hotelu AND h.nazwa_hotelu='mercury'; b) Wypisanie informacji na temat rezerwacji, które dzisiaj mają zostać zrealizowane SELECT nr_rezerwacji, nr_id_klienta, nazwa_hotelu, data_przyjazdu, FROM rezerwacje WHERE data_przyjazdu=current_date; c) Sprawdzenie ile razy dana osoba byla gościem tej sieci hoteli SELECT count(*) AS ilosc, nr_id_klienta FROM historia_pobytow GROUP BY nr_id_klienta; d) Sprawdzenie ile klient o numerze id równym 10 ma do zaplaty SELECT platnosc(10); e) Przeniesienie klientow wymeldowanych do tabeli historia_pobytow SELECT aktualizuj_mieszkancow();