DROP TABLE IF EXISTS Historia_Ekspozycji CASCADE; DROP TABLE IF EXISTS Eksponat CASCADE; DROP TABLE IF EXISTS Autor CASCADE; DROP TABLE IF EXISTS Galeria CASCADE; DROP TABLE IF EXISTS Instytucje CASCADE; CREATE TABLE Autor ( ID SERIAL PRIMARY KEY, Imie VARCHAR(20) NOT NULL, Nazwisko VARCHAR(20) NOT NULL, Rok_urodzenia INTEGER NOT NULL CHECK (Rok_urodzenia > 0 AND Rok_urodzenia <= EXTRACT(YEAR FROM CURRENT_DATE)), Rok_smierci INTEGER CHECK (Rok_smierci IS NULL OR Rok_smierci > Rok_urodzenia) ); CREATE TABLE Eksponat ( ID SERIAL PRIMARY KEY, Tytul VARCHAR(100) NOT NULL, Typ VARCHAR(20) NOT NULL CHECK (Typ IN ('obraz', 'rzeźba', 'fotografia')), Wysokosc NUMERIC(5,2) NOT NULL CHECK (Wysokosc > 0), Szerokosc NUMERIC(5,2) NOT NULL CHECK (Szerokosc > 0), Waga INTEGER NOT NULL CHECK (Waga > 0), Autor_ID INTEGER NOT NULL REFERENCES Autor(ID) ON DELETE CASCADE ); CREATE TABLE Galeria ( ID SERIAL PRIMARY KEY, Nazwa VARCHAR(100) NOT NULL, Adres VARCHAR(100) NOT NULL, Sala VARCHAR(20) NOT NULL ); CREATE TABLE Instytucje ( ID SERIAL PRIMARY KEY, Nazwa VARCHAR(100) NOT NULL, Miasto VARCHAR(100) NOT NULL ); CREATE TABLE Historia_Ekspozycji ( Historia_ID SERIAL PRIMARY KEY, Typ_wydarzenia VARCHAR(20) NOT NULL CHECK (Typ_wydarzenia IN ('wystawa', 'wypozyczenie')), Data_rozpoczecia DATE NOT NULL, Data_zakonczenia DATE NOT NULL CHECK (Data_zakonczenia >= Data_rozpoczecia), Instytucje_ID INTEGER REFERENCES Instytucje(ID) ON DELETE SET NULL, Galeria_ID INTEGER REFERENCES Galeria(ID) ON DELETE SET NULL, Eksponat_ID INTEGER NOT NULL REFERENCES Eksponat(ID) ON DELETE CASCADE ); CREATE OR REPLACE FUNCTION ZmienPozycjeEksponatu( eksponat_id INT, galeria_id INT, instytucja_id INT, typ_wydarzenia VARCHAR, data_rozpoczecia DATE, data_zakonczenia DATE ) RETURNS VOID AS $$ BEGIN -- Sprawdzenie, czy eksponat istnieje IF NOT EXISTS (SELECT 1 FROM Eksponat WHERE ID = eksponat_id) THEN RAISE EXCEPTION 'Eksponat o podanym ID nie istnieje'; END IF; -- Dodanie nowego rekordu do historii ekspozycji INSERT INTO Historia_Ekspozycji ( Typ_wydarzenia, Data_rozpoczecia, Data_zakonczenia, Instytucje_ID, Galeria_ID, Eksponat_ID ) VALUES (typ_wydarzenia, data_rozpoczecia, data_zakonczenia, instytucja_id, galeria_id, eksponat_id); END; $$ LANGUAGE plpgsql; -- Maksymalny czas wypożyczenia eksponatu ALTER TABLE Historia_Ekspozycji ADD CONSTRAINT MaxCzasWypozyczenia CHECK ( (Typ_wydarzenia = 'wypozyczenie' AND Data_zakonczenia - Data_rozpoczecia <= 30) OR Typ_wydarzenia != 'wypozyczenie' ); -- Sprawdzenie minimalnej liczby eksponatów artysty w muzeum CREATE OR REPLACE FUNCTION SprawdzEksponatyArtysty() RETURNS TRIGGER AS $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM Eksponat WHERE Autor_ID = OLD.Autor_ID AND ID NOT IN ( SELECT Eksponat_ID FROM Historia_Ekspozycji WHERE Typ_wydarzenia = 'wypozyczenie' AND Data_zakonczenia > CURRENT_DATE ) ) THEN RAISE EXCEPTION 'Każdy artysta musi mieć co najmniej jeden eksponat w muzeum'; END IF; RETURN OLD; END; $$ LANGUAGE plpgsql; CREATE TRIGGER SprawdzEksponatyArtystyTrigger AFTER DELETE OR UPDATE ON Eksponat FOR EACH ROW EXECUTE FUNCTION SprawdzEksponatyArtysty();