参照制約をつけたら追加/削除できなくなったでござるの巻
事象
これはOKなケース
CREATE TABLE table1 (col1 VARCHAR(5) PRIMARY KEY); CREATE TABLE table2 (col2 VARCHAR(5) PRIMARY KEY); CREATE TABLE table3 ( col3 VARCHAR(5) REFERENCES table1(col1), col4 VARCHAR(5) REFERENCES table2(col2), primary key(col3, col4)); INSERT INTO table1 values ('aaa'); INSERT INTO table2 values ('bbb'); INSERT INTO table3 values ('aaa', 'bbb');
これはNG
CREATE TABLE table4 (col1 VARCHAR(5) PRIMARY KEY); CREATE TABLE table5 (col2 VARCHAR(5) PRIMARY KEY); CREATE TABLE table6 ( col3 VARCHAR(5) REFERENCES table1(col1) PRIMARY KEY, col4 VARCHAR(5) REFERENCES table2(col2)); INSERT INTO table4 values ('aaa'); INSERT INTO table5 values ('bbb'); INSERT INTO table6 values ('aaa', 'bbb'); 5312: Aborted due to a non-valid reference index on user_name.table6.
- 参照索引(Reference Index = RI)が悪さしてそう。
- どう考えても主キーの構成が関係してそう。
ここと同じ事象か?
How to validate the invalid references created [From Vireta_Godinho: Wed, 14 Jun 2006 @ 10:51 GMT]
調査結果
- col4のRIなしで作り直しても駄目
- col3, col4ともRIなしはOK
- WITH CHECK / NO CHECK OPTIONを付けて作り直しても駄目。
いろいろ調べた結果、DBC.ALL_RI_Parents / DBC.ALL_RI_Childrenを見ても、table6.col4に設定したはずのRIが存在しない事に気がついた。
ちなみに、col3のRIは存在する。
また、table3の方は、col3, col4ともRIが存在する。
つまり、CREATE TABLE時に参照制約を付与する場合、主キー*1の部分キーでないと、RIを作ってくれないらしい。
多分、RIがないのにチェックして落ちてるんじゃないだろうか?
そこで、Re: How to validate the invalid references created [From Waters, Gerald: Fri, 16 Jun 2006 @ 11:09 GMT]の内容を参考に、以下のとおり試してみたら、ちゃんとRIが確認できました。
- CREATE TABLE時には、非主キー項目は参照制約を付与しないこと
- ALTER TABLEで参照制約を付与
調べてる最中に失敗した内容が見当つくと良いんだけど…。
テーブルの構造とRIは別なのかも。(テーブルをドロップしてもカスケードされない?)
追記
ALTER TABLEで参照制約を付与すると、勝手にテーブルが作られます。
*1:もしくは、PIの方が妥当か?