интересная проблема.Я бы подошел к этому следующим образом:
CREATE TABLE t123_fk(
FK_1 int,
FK_2 int,
CONSTRAINT t123_fk_pk PRIMARY KEY(FK_1, FK_2),
CONSTRAINT fk_2_is_new_constr_violated UNIQUE(FK_1)
);
CREATE TABLE t123(
ID int,
FK_1 int,
FK_2 int,
NAME varchar2(100),
constraint t123_fk FOREIGN KEY(FK_1, FK_2) REFERENCES t123_fk
);
CREATE OR REPLACE TRIGGER some_name
BEFORE INSERT OR UPDATE ON t123
FOR EACH ROW
BEGIN
INSERT INTO t123_fk( fk_1, fk_2 )
SELECT :new.FK_1, :new.FK_2 FROM dual
WHERE NOT EXISTS(
SELECT 1 FROM t123_fk
WHERE fk_1 = :new.fk_1 AND fk_2 = :new.fk_2
);
END;
/
Таблица t123
- это главная таблица, содержащая наши данные.
Таблица t123_fk
и триггер являются вспомогательными и используются только для того, чтобы помочь нам форсировать наше ограничение (кстати, наше ограничение называется fk_2_is_new_constr_violated
в приведенном выше коде).
Здесьэто тест - четвертая вставка будет отклонена базой данных:
insert into t123( id, fk_1, fk_2, name) values(1,2,3,'X01');
insert into t123( id, fk_1, fk_2, name) values(2,2,3,'X01-A');
insert into t123( id, fk_1, fk_2, name) values(3,2,3,'X01');
insert into t123( id, fk_1, fk_2, name) values(4,2,4,'X01'); // this insert will be rejected
insert into t123( id, fk_1, fk_2, name) values(5,3,5,'X01');