web-dev-qa-db-ja.com

Oracleでの外部キーの作成エラー

2つのテーブルがあります。

PRODUCTS

PREFIX      SUFFIX      ATTR1   ATTR2
-----------------------------------------------------
001         AAA         50      100
001         BBB         20      300
010         ACC         50      500
100         ABC         10      200
100         CBA         30      200
100         BBB         10      100

OPTIONS

PREFIX      SUFFIX      OPT_CODE    
----------------------------------------
001         AAA         A1
001         AAA         A2
001         AAA         A3
001         BBB         A2
001         BBB         A1
001         BBB         A3
100         ABC         A1
100         CBA         B1
100         BBB         A2

このDDLで作成:

create table products (
    prefix VARCHAR2(10),
    suffix VARCHAR2(10),
    attr1  VARCHAR2(100),
    attr2  VARCHAR2(100)
    )

create table options (
    prefix VARCHAR2(10),
    suffix VARCHAR2(10),
    opt_code VARCHAR2(2)
    )

Productsテーブルに主キーを作成しました:

alter table products add constraint products_pk primary key (prefix, suffix);

オプションテーブルの主キー:

alter table options add constraint options_pk primary key (prefix, suffix, opt_code);

次のように外部キーをオプションテーブルに追加しようとすると、

ALTER TABLE options ADD CONSTRAINT fk_options_products FOREIGN KEY (prefix, suffix)
   REFERENCES products (prefix, suffix);

このエラーが発生しています:

SQL Error: ORA-02298: cannot validate (PRODDB.FK_OPTIONS_PRODUCTS) - parent keys not found
02298. 00000 - "cannot validate (%s.%s) - parent keys not found"
*Cause:    an alter table validating constraint failed because the table has
           child records.
*Action:   Obvious

すべての子レコード(OPTIONS内)が親テーブル(PRODUCTS)にエントリを持っていることを検証しましたが、PRODUCTS内のすべてのエントリがOPTIONSに子エントリを持っているわけではありません。

そのエラーについての私の理解-あなたは子エントリの親レコードがないときにそれを取得します。

ここで何か不足していますか?

3
skylaneffz

これをデバッグできます。 EXCEPTIONS句を含む以下のコードでFKを作成します。エラーの原因となっている子テーブルoptionsの特定の行を特定します。

CREATE TABLE fk_exceptions (
    row_id     ROWID
  , owner      VARCHAR2(30)
  , table_name VARCHAR2(30)
  , constraint VARCHAR2(30)
);

ALTER TABLE options
  ADD CONSTRAINT fk_options_products
  FOREIGN KEY (prefix, suffix)
  REFERENCES products (prefix, suffix)
  EXCEPTIONS INTO fk_exceptions;

あなたはまだあなたのORA-02298、ただし証拠は収集され、fk_exceptions テーブル。犯人の行は次のように明らかにされます:

SELECT * FROM options WHERE rowid IN (SELECT row_id FROM fk_exceptions);
4
Joshua Huber