方法を宣言する外部キーとOR条件をOracle?
質問
いテーブル(A)主キーのいずれかの外部キーテーブル(B)またはテーブル(C)
create table A (
akey number,
txt varchar2(10)
);
create table B (
bkey number,
txt varchar2(10)
);
create table C (
ckey number,
txt varchar2(10)
);
だいたいというように:
alter table A add constraint BorCkey foreign key (akey) references B(bkey)` or C(ckey);
可能ですか?
解決
いうことはできませんでますので、Oracle社
オプション一般的には
- 作成の異なる二つのカラム(bkeyとckey)がbkey参考B.bkeyとckey参考C.ckeyを制約ることを保証するのみがNULLでない場合はどの時点ます。
- をある種の"合B&CるB&Cは外部キーに対する外部キーカラム参照のこの組み合わせる。
したい場合に制約を保証することをちょうど一つのカラムがNULLの場合、一つがNULLでない場合には当行
create table one_key(
col1 number,
col2 number,
check( nvl2(col1,1,0) + nvl2(col2,1,0) = 1 )
)
他のヒント
外部のキーの制約は次のとおりです 1つの外国のテーブル.
つまり、この状況で2つの変更テーブルステートメントを使用して、2つのテーブルを参照するために外部キーをセットアップする必要があります。関係を指定する機会はありません。 A.akey
両方に存在する必要があります B.bkey
と C.ckey
同時に. 。たとえば、if B.bkey
nullの値がありますが C.ckey
そうではありません - それでは A.akey
nullの値を持つことはできません。外国の鍵はOracleでは延期可能ですが、説明されている動作は、両方の外部キーが同時に有効になっている場合に遭遇するものです。すべての値が関係を満たさない場合、制約を有効にすることはできません。
この作業を行うために2つのテーブルを必要としないように、関係を簡素化する方法のニーズを確認する必要があります。
何らかの形のサブタイプ/スーパータイプの関係が進行しているように聞こえます。典型的な例は、「顧客」または「サプライヤー」のいずれかである「人」です。
Person_idの一意のキーとPerson_Type( 'CUST'または 'SUPP')の属性と属性の一意のキーがある場合があります。 person_idで主要なキーを作成すると、person_typeサブタイプテーブル(サプライヤー/顧客)でそれを参照できます。
次に、Person_IDに一意の制約を追加して、Person_IDの値が顧客またはサプライヤーであるが両方ではなく、サブタイプのテーブルの制約を確認して、テーブルに1つのタイプのみが表されるように制約を確認する必要があることを確認します。
create table person
(person_id number,
person_type varchar2(4),
name varchar2(10),
constraint person_pk primary key (person_id, person_type),
constraint person_id_uk unique (person_id));
create table supplier
(supplier_id number,
supplier_type varchar2(4),
blah varchar2(10),
constraint supplier_pk primary key (supplier_id, supplier_type),
constraint supp_pers_fk foreign key (supplier_id, supplier_type)
REFERENCES person (person_id, person_type)
)
/
alter table supplier add constraint supp_type_ck check (supplier_type = 'SUPP');
それはきれいではありませんが、タイプ/サブタイプはリレーショナルの概念よりもオブジェクトの概念です。
ジャスティンに触発された私の解決策:
CREATE OR REPLACE TRIGGER abc
BEFORE INSERT OR UPDATE ON a
FOR EACH ROW
DECLARE
v_testB NUMBER:= 0;
v_testC NUMBER:= 0;
BEGIN
SELECT
COUNT(bkey)
INTO
v_testB
FROM
b
WHERE
bkey = :new.aKey;
SELECT
COUNT(ckey)
INTO
v_testC
FROM
c
WHERE
ckey = :new.aKey;
IF ((v_testB + v_testC) <> 1) THEN
RAISE_APPLICATION_ERROR(-20002,'Foreign key to B or C missing.');
END IF;
END;
/
SHOW ERRORS TRIGGER abc
組合がB&Cを表にテーブルするという具体化されたビューを作成し、FKの制約をビューに向けてください