2つのテーブルのうち片方にのみ存在するレコードの論理削除
やりたいこと
2つのテーブルを比較し、一方に存在し、もう一方に存在しないレコードを論理削除します。
データ連携などの際に連携されなかったマスタ情報などを更新するために使用します。
UPDATEだけでなく、DELETEなどの応用も可能です。
この処理では「TGTテーブル」に存在し、「WKテーブル」に存在しないものを「TGTテーブル」でUPDATEする場合に使用します。
逆に「WKテーブル」に存在し、「TGTテーブル」に存在しないものを「WKテーブル」からINSERTする場合には「MERGE」文を使用します。
【PL/SQL】MERGE=INSERT+UPDATE
テーブル
WKテーブル
EMP_CD(主キー) | EMP_NAME |
---|---|
E111111 | aaa |
E222222 | bbb |
TGTテーブル
EMP_CD(主キー) | EMP_NAME | DEL_FLG(削除区分) |
---|---|---|
E111111 | aaa | 0 |
E222222 | bbb | 0 |
E333333 | ccc | 0 |
⇒TGTテーブルのみに存在するレコードのDEL_FLGを1として論理削除を行いたい。
EMP_CD(主キー) | EMP_NAME | DEL_FLG(削除区分) |
---|---|---|
E111111 | aaa | 0 |
E222222 | bbb | 0 |
E333333 | ccc | 1 |
コード(主キーが1つの場合)
UPDATE tgt tgt
SET tgt.del_flg = '1' -- del_flgを1に更新
WHERE tgt.emd_cd =
( SELECT
tgt_wk.emd_cd
FROM tgt tgt_wk -- TGTテーブル
LEFT OUTER JOIN wk wk -- WKテーブル
ON tgt_wk.emd_cd = wk.emd_cd
WHERE wk.emd_cd IS NULL -- 主キーがNULLの項目をキャッチ
);
または
UPDATE tgt tgt
SET tgt.del_flg = '1' -- del_flgを1に更新
WHERE NOT EXISTS
(SELECT *
FROM wk
WHERE tgt.emp_cd = wk.emp_cd
);
EXISTS
は後に続く括弧で囲まれた副問い合わせの結果が「存在すれば (TRUE)」、「存在しなければ (FALSE)」を戻します。
NOT EXISTS
はその逆のため、「存在しなければ (TRUE)」、「存在すれば (FALSE)」を戻します。
コード(主キーが2つ以上の場合)
主キーがemp_cd
とemp_cd2
の場合には以下のような記述になります。
UPDATE tgt tgt
SET tgt.del_flg = '1' -- del_flgを1に更新
WHERE ( tgt.emd_cd,
tgt.emd_cd2
) IN
( SELECT
tgt_wk.emd_cd,
tgt_wk.emd_cd2
FROM tgt tgt_wk -- TGTテーブル
LEFT OUTER JOIN wk wk -- WKテーブル
ON tgt_wk.emd_cd = wk.emd_cd
WHERE wk.emd_cd IS NULL -- 主キーがNULLの項目をキャッチ
AND wk.emd_cd2 IS NULL
);
または
UPDATE tgt tgt
SET tgt.del_flg = '1' -- del_flgを1に更新
WHERE NOT EXISTS
(SELECT *
FROM wk
WHERE tgt.emp_cd = wk.emp_cd
AND tgt.emp_cd2 = wk.emp_cd2
);
NOT EXISTS とNOT IN
NOT EXISTS
ではなくNOT IN
を使用した場合、副問い合わせの結果が NULLとなる場合、結果はUNKNOWNになるため NOT EXISTS
の場合と異なる挙動を取ります。NULLについて特別な処理を行わないならば、NOT EXISTS
が無難です。