外部キー(参照制約)を付けた表では、次の2つのエラーがよく出ます。
SQL0530N The insert or update value of the FOREIGN KEY
"DB2INST1.EMPLOYEE.RED" is not equal to any value of the parent key of the
parent table. SQLSTATE=23503
SQL0532N A parent row cannot be deleted because the relationship
"DB2INST1.PROJECT.FK_PROJECT_1" restricts the deletion. SQLSTATE=23001
上は SAMPLE データベースで、存在しない部門の社員を登録したときと、部門 A00 を消そうとしたときのものです。
まず見る(結論)
引用符の中は スキーマ.子の表.制約名 です。親を消そうとして出たエラーでも、表示されるのは子の表です。制約名で SYSCAT.REFERENCES を引くと、親の表と列が分かります。
SELECT TABNAME, REFTABNAME, FK_COLNAMES, PK_COLNAMES, DELETERULE
FROM SYSCAT.REFERENCES WHERE CONSTNAME = 'FK_PROJECT_1'
親を消す前は、WHERE REFTABNAME = '親の表' で親を参照している制約を全部引きます。メッセージに出るのは止めた制約1つだけです。
症状 → 原因 → 対処(逆引き)
| 症状 | よくある原因 | まず打つ手 |
|---|---|---|
子への INSERT / UPDATE で SQL0530N |
親に無い値を入れた | 先に親の行を作る。親が決まらないなら NULL |
親の DELETE で SQL0532N |
子が参照している | 子を消すか付け替える。ON DELETE CASCADE / SET NULL を検討 |
親キーの UPDATE で SQL0531N |
子が参照している | 子を付け替えてから親を変える |
親の TRUNCATE で SQL20356N |
参照制約の親は TRUNCATE できない |
DELETE を使う |
制約名が SQL2610... のような数字 |
名前を付けずに作った外部キー | SYSCAT.REFERENCES で引く |
LOAD した子の表が SQL0668N 理由コード 1 |
LOAD は外部キーを検査しない |
例外表を作って SET INTEGRITY ... FOR EXCEPTION |
親の表を DROP したら外部キーが消えていた |
親の DROP TABLE は通り、子の外部キーも一緒に消える |
DROP 前に外部キーの定義を控える |
外部キーの列が NULL の行は検査されず、親が無くても入りました。SQL0532N の SQLSTATE は、削除規則が NO ACTION(既定)だと 23504、RESTRICT だと 23001 でした。
それでも切り分けられないとき(実機ログつきの詳解)
SAMPLE の DEPARTMENT を参照する3つの制約が削除規則ごとにどう振る舞うか、LOAD で入った孤児行を SET INTEGRITY で例外表に移す手順、親の DROP TABLE の結果は、Zennのフル記事にまとめています。
この記事のような現場のTIPSを、Db2運用の全体像として12章に体系化しました。公式マニュアルには載らない「あのとき知っていれば」を減らすための1冊です。
現場で引ける Db2 の教科書
現場で引ける!Db2実践エンジニア・バイブル
Db2はRDBMS市場でシェア数%。情報が少なく、頼れるのは膨大な公式マニュアルだけ―― そんな現状を変えたくて、「なぜこの値にするのか」「この障害のとき次に何を見るのか」という、マニュアルに載っていない現場の文脈を1冊にまとめました。書いてあることはすべて実際の現場で経験したことです。
アーキテクチャ/構成パラメーター選定/セキュリティ/バックアップ・リカバリ/HADR/pureScale/日常点検の自動化/メモリ・ロック競合/SQLチューニング/RUNSTATS・REORG/MON_GET監視/現場の難題集 ―― 全12章+運用シェルスクリプト集。