概要
同一構造のテーブルが2個あり、一方のテーブルへの更新を他方のテーブルへも反映したい。そんな時に使えそう。
前提条件
-
同一構造のテーブル TBL_A, TBL_B があり、主キーが KEY1, KEY2 とする。
-
TBL_Aに対して書き込み(INSERT, UPDATE, DELETE)があり、それをTBL_Bへ反映する想定。
-
全レコード削除&全レコード挿入、というワイルドなことはしたくない。
-
KEY1, KEY2が同じで、それ以外の列が更新されている場合にも対応すること。
TBL_B にあって TBL_A にない行を削除
以下のSQLを実行すると、TBL_Bにのみ存在する行を抽出し、TBL_Bから削除する。
TBL_AとTBL_Bで完全に一致する行以外をMINUS演算子が抽出するので、KEY1, KEY2が同じでそれ以外の列が違う値の場合も削除される。
delete from TBL_B where (KEY1, KEY2) in (
select KEY1, KEY2 from (
select * from TBL_B
MINUS
select * from TBL_A
)
);
この時点で、TBL_BにはTBL_Aに存在する行(内容が完全に一致する行)が残っている。
TBL_A にあって TBL_B にない行を挿入
以下のSQLを実行すると、TBL_Aにのみ存在する行を抽出し、TBL_Bに挿入する。
insert into TBL_B (
select * from TBL_A
MINUS
select * from TBL_B
);
使ってみた感想
主キー以外の列を * で指定できるので、列数が多いテーブルのときに楽(笑)
2個のテーブルが異なるDBインスタンスの場合、データベースリンクやシノニムを使って両方のテーブルを同時に操作できるようにしておく。
実行速度はレコード数によって変わってくるはずなので、本番環境に近い状態で試してみないと何とも言えない。
以上。