Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como posso garantir a integridade entre tabelas não relacionadas?


Você pode fazer isso usando redundância controlada e restrições FK compostas:
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)
);

Adicionei uma chave exclusiva composta (offr_id, coy_id) para dar suporte a uma restrição FK composta no subscribe tabela.
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)
);

A chave primária composta aqui é perfeita para uma restrição FK composta no subscribe tabela.
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)
);

A sobreposição de restrições FK compostas garantirá que um oficial só possa assinar o seguro oferecido pela empresa em que está inscrito. coy_id é logicamente redundante, mas necessário para a integridade e não há risco de anomalias de atualização devido às restrições FK.

Como alternativa, você pode usar gatilhos para verificar se os valores estão relacionados por meio de junções internas:
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');

Isenção de responsabilidade:não consegui testar isso no SqlFiddle e não tenho o Oracle instalado, mas espero que ele aponte na direção certa.