Oracle
 sql >> Database >  >> RDS >> Oracle

Come posso garantire l'integrità tra tabelle non correlate?

Puoi farlo utilizzando la ridondanza controllata e i vincoli FK compositi:

CREATE TABLE offr (
    offr_id INT NOT NULL,
    coy_id INT NOT NULL,
    PRIMARY KEY (offr_id),
    FOREIGN KEY (coy_id) REFERENCES ins_coy (coy_id),
    UNIQUE KEY (offr_id, coy_id)
);

Ho aggiunto una chiave univoca composita (offr_id, coy_id) per supportare un vincolo FK composito su subscribe tabella.

CREATE TABLE provide (
    coy_id INT NOT NULL,
    type_id INT NOT NULL,
    PRIMARY KEY (coy_id, type_id),
    FOREIGN KEY (coy_id) REFERENCES ins_coy (coy_id)
);

La chiave primaria composita qui è perfetta per un vincolo FK composito su subscribe tabella.

CREATE TABLE subscribe (
    naf_no INT NOT NULL,
    coy_id INT NOT NULL,
    type_id INT NOT NULL,
    PRIMARY KEY (naf_no, type_id),
    FOREIGN KEY (naf_no, coy_id) REFERENCES offr (offr_id, coy_id),
    FOREIGN KEY (coy_id, type_id) REFERENCES provide (coy_id, type_id)
);

La sovrapposizione di vincoli FK compositi assicurerà che un funzionario possa sottoscrivere solo l'assicurazione offerta dalla società in cui è iscritto. coy_id è logicamente ridondante ma necessario per l'integrità e non vi è alcun rischio di anomalie di aggiornamento dovute ai vincoli FK.

In alternativa, puoi utilizzare i trigger per verificare che i valori siano correlati tramite inner join:

CREATE TRIGGER check_subscribe BEFORE INSERT OR UPDATE ON subscribe
FOR EACH ROW
WHEN NOT EXISTS (
    SELECT 1
    FROM offr
    INNER JOIN provide ON offr.coy_id = provide.coy_id
    WHERE offr.offr_id = new.naf_no AND provide.type_id = new.type_id
)
RAISE_APPLICATION_ERROR (num => -20000, msg => 'Officers can only subscribe to types provided by their company');

Dichiarazione di non responsabilità:non sono stato in grado di testarlo su SqlFiddle e non ho installato Oracle, ma spero che ti indichi nella giusta direzione.