Ограничения целостности в SQL - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь создать новую базу данных в SQL. Итак, я написал этот код ;

CREATE TABLE datum (
    datum_zajezdu       DATE NOT NULL,
    zajezd_id           INTEGER NOT NULL,
    pruvodci_osoba_id   INTEGER NOT NULL,
    zajezd_zajezd_id1   NUMBER NOT NULL
);

ALTER TABLE datum
    ADD CONSTRAINT datum_pk PRIMARY KEY ( datum_zajezdu,
    zajezd_id,
    pruvodci_osoba_id );

CREATE TABLE osoba (
    osoba_id   INTEGER NOT NULL,
    jmeno      VARCHAR2(32 CHAR) NOT NULL,
    prijmeni   VARCHAR2(32 CHAR) NOT NULL
);

ALTER TABLE osoba ADD CONSTRAINT osoba_pk PRIMARY KEY ( osoba_id );

CREATE TABLE pracovnik (
    misnost_id                   INTEGER NOT NULL,
    zamestnanec_osoba_osoba_id   INTEGER NOT NULL
);

ALTER TABLE pracovnik ADD CONSTRAINT pracovnik_pk PRIMARY KEY ( zamestnanec_osoba_osoba_id );

CREATE TABLE pruvodci (
    tel                          INTEGER NOT NULL,
    mail                         VARCHAR2(32 CHAR) NOT NULL,
    zamestnanec_osoba_osoba_id   INTEGER NOT NULL
);

ALTER TABLE pruvodci ADD CONSTRAINT pruvodci_pk PRIMARY KEY ( zamestnanec_osoba_osoba_id );

CREATE TABLE rezervace (
    rezervace_id              INTEGER NOT NULL,
    zakaznik_osoba_osoba_id   INTEGER NOT NULL,
    zajezd_zajezd_id          INTEGER NOT NULL,
    pracovnik_osoba_id        INTEGER NOT NULL
);

ALTER TABLE rezervace ADD CONSTRAINT rezervace_pk PRIMARY KEY ( rezervace_id );

CREATE TABLE typ_cestovani (
    nazev_typu   VARCHAR2(30 CHAR) NOT NULL
);

ALTER TABLE typ_cestovani ADD CONSTRAINT typ_cestovani_pk PRIMARY KEY ( nazev_typu );

CREATE TABLE zajezd (
    zajezd_id    INTEGER NOT NULL,
    nazev        VARCHAR2(32 CHAR) NOT NULL,
    stat         VARCHAR2(32 CHAR) NOT NULL,
    mesto        VARCHAR2(32 CHAR) NOT NULL,
    cena         NUMBER NOT NULL,
    zajezd_id1   NUMBER NOT NULL
);

ALTER TABLE zajezd ADD CONSTRAINT zajezd_pk PRIMARY KEY ( zajezd_id1 );

CREATE TABLE zajezd_ma_typ (
    typ_cestovani_nazev_typu   VARCHAR2(30 CHAR) NOT NULL,
    zajezd_zajezd_id           INTEGER NOT NULL
);

ALTER TABLE zajezd_ma_typ ADD CONSTRAINT zajezd_ma_typ_pk PRIMARY KEY ( typ_cestovani_nazev_typu,
zajezd_zajezd_id );

CREATE TABLE zakaznik (
    tel              INTEGER NOT NULL,
    mail             VARCHAR2(32 CHAR),
    osoba_osoba_id   INTEGER NOT NULL
);

ALTER TABLE zakaznik ADD CONSTRAINT zakaznik_pk PRIMARY KEY ( osoba_osoba_id );

CREATE TABLE zamestnanec (
    cislo_uctu       INTEGER NOT NULL,
    osoba_osoba_id   INTEGER NOT NULL
);

ALTER TABLE zamestnanec
    ADD CONSTRAINT arc_1_lov CHECK ( osoba_osoba_id IN (
        '1',
        '2'
    ) );

ALTER TABLE zamestnanec ADD CONSTRAINT zamestnanec_pk PRIMARY KEY ( osoba_osoba_id );

ALTER TABLE datum
    ADD CONSTRAINT datum_pruvodci_fk FOREIGN KEY ( pruvodci_osoba_id )
        REFERENCES pruvodci ( zamestnanec_osoba_osoba_id );

ALTER TABLE datum
    ADD CONSTRAINT datum_zajezd_fk FOREIGN KEY ( zajezd_zajezd_id1 )
        REFERENCES zajezd ( zajezd_id1 );

ALTER TABLE pracovnik
    ADD CONSTRAINT pracovnik_zamestnanec_fk FOREIGN KEY ( zamestnanec_osoba_osoba_id )
        REFERENCES zamestnanec ( osoba_osoba_id );

ALTER TABLE pruvodci
    ADD CONSTRAINT pruvodci_zamestnanec_fk FOREIGN KEY ( zamestnanec_osoba_osoba_id )
        REFERENCES zamestnanec ( osoba_osoba_id );

ALTER TABLE rezervace
    ADD CONSTRAINT rezervace_pracovnik_fk FOREIGN KEY ( pracovnik_osoba_id )
        REFERENCES pracovnik ( zamestnanec_osoba_osoba_id );

ALTER TABLE rezervace
    ADD CONSTRAINT rezervace_zajezd_fk FOREIGN KEY ( zajezd_zajezd_id )
        REFERENCES zajezd ( zajezd_id );

ALTER TABLE rezervace
    ADD CONSTRAINT rezervace_zakaznik_fk FOREIGN KEY ( zakaznik_osoba_osoba_id )
        REFERENCES zakaznik ( osoba_osoba_id );

ALTER TABLE zajezd_ma_typ
    ADD CONSTRAINT zajezd_ma_typ_typ_cestovani_fk FOREIGN KEY ( typ_cestovani_nazev_typu )
        REFERENCES typ_cestovani ( nazev_typu );

ALTER TABLE zajezd_ma_typ
    ADD CONSTRAINT zajezd_ma_typ_zajezd_fk FOREIGN KEY ( zajezd_zajezd_id )
        REFERENCES zajezd ( zajezd_id );

ALTER TABLE zakaznik
    ADD CONSTRAINT zakaznik_osoba_fk FOREIGN KEY ( osoba_osoba_id )
        REFERENCES osoba ( osoba_id );

ALTER TABLE zamestnanec
    ADD CONSTRAINT zamestnanec_osoba_fk FOREIGN KEY ( osoba_osoba_id )
        REFERENCES osoba ( osoba_id );

CREATE OR REPLACE TRIGGER arc_arc_1_pracovnik BEFORE
    INSERT OR UPDATE OF zamestnanec_osoba_osoba_id ON pracovnik
    FOR EACH ROW
DECLARE
    d   INTEGER;
BEGIN
    SELECT
        a.osoba_osoba_id
    INTO
        d
    FROM
        zamestnanec a
    WHERE
        a.osoba_osoba_id =:new.zamestnanec_osoba_osoba_id;

    IF
        ( d IS NULL OR d <> 1 )
    THEN
        raise_application_error(-20223,'FK Pracovnik_Zamestnanec_FK in Table Pracovnik violates Arc constraint on Table Zamestnanec - discriminator column Osoba_osoba_id doesn''t have value 1'
);
    END IF;

EXCEPTION
    WHEN no_data_found THEN
        NULL;
    WHEN OTHERS THEN
        RAISE;
END;
/

CREATE OR REPLACE TRIGGER arc_arc_1_pruvodci BEFORE
    INSERT OR UPDATE OF zamestnanec_osoba_osoba_id ON pruvodci
    FOR EACH ROW
DECLARE
    d   INTEGER;
BEGIN
    SELECT
        a.osoba_osoba_id
    INTO
        d
    FROM
        zamestnanec a
    WHERE
        a.osoba_osoba_id =:new.zamestnanec_osoba_osoba_id;

    IF
        ( d IS NULL OR d <> 2 )
    THEN
        raise_application_error(-20223,'FK Pruvodci_Zamestnanec_FK in Table Pruvodci violates Arc constraint on Table Zamestnanec - discriminator column Osoba_osoba_id doesn''t have value 2'
);
    END IF;

EXCEPTION
    WHEN no_data_found THEN
        NULL;
    WHEN OTHERS THEN
        RAISE;
END;
/

CREATE SEQUENCE zajezd_zajezd_id1_seq START WITH 1 NOCACHE ORDER;

CREATE OR REPLACE TRIGGER zajezd_zajezd_id1_trg BEFORE
    INSERT ON zajezd
    FOR EACH ROW
    WHEN ( new.zajezd_id1 IS NULL )
BEGIN
    :new.zajezd_id1 := zajezd_zajezd_id1_seq.nextval;
END;

В результате я должен получить что-то вроде: this (реляционная схема)

но у меня есть одна проблема. В моей логической схеме я установил 2 ограничения целостности и не знаю, как записать это в файл create.sql.

Первый: «Особа» должно быть «Заместнанец» или «Заказник», или оба. «Особа» не может быть без отношения.

Второй: «Osoba» не может получить резервирование (ENTITY «Rezervace»), если «Osoba» является «Pruvodci» и имеет собственную работу в ту же дату (сущность «datum»), что и резервирование.

РЕДАКТИРОВАТЬ: моя логическая схема выглядит

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...