SQL中的完整性限制

时间:2018-04-27 15:21:24

标签: sql oracle database-design

我正在尝试在SQL中创建一个新数据库。 所以,我已经写了code;

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 (relational schema)

但我有一个问题。在我的逻辑架构中,我提出了2个完整性限制,我不知道如何在create.sql文件中编写它。

首先是:  &#34; Osoba&#34;应该是&#34; Zamestnanec&#34;或者&#34; Zakaznik&#34;或两者兼而有之。&#34; Osoba&#34;不能没有任何关系。

第二个: &#34; Osoba&#34;如果&#34; Osoba&#34;无法预订(ENTITY&#34; Rezervace&#34;)是&#34; Pruvodci&#34;并且在同一日期(实体&#34;数据&#34;)作为预订有自己的工作。

编辑:我的逻辑架构looks

0 个答案:

没有答案