Oracleマージを使用して挿入と削除を行うが、更新はできない方法はありますか?
別のテーブルの1つの行に関連する一連の値を表すテーブルがあります。値のセットをすべて削除して新しいセットを追加するか、一部を選択的に削除してその他を追加することで、値のセットを変更できますが、可能であればそれを単一のステートメントにすることに興味があります。
以下は、更新を伴う実際の例です。これを機能させるには、dummy
を追加して、on
条件にない列を更新できるようにする必要がありました。更新するダミー列なしで削除と挿入のみを行う方法はありますか?
実際に更新されていなくても、on
条件の列がupdate set
リストに含まれていない可能性があります。
create table every_value ( the_value varchar2(32) );
create table paired_value ( the_id number, a_value varchar2(32) , dummy number default 0 );
-- the_id is a foreign_key to a row in another table
insert into every_value ( the_value ) values ( 'aaa' );
insert into every_value ( the_value ) values ( 'abc' );
insert into every_value ( the_value ) values ( 'ace' );
insert into every_value ( the_value ) values ( 'adg' );
insert into every_value ( the_value ) values ( 'aei' );
insert into every_value ( the_value ) values ( 'afk' );
-- pair ace and afk with id 3
merge into paired_value p using every_value e
on ( p.the_id = 3 and p.a_value = e.the_value )
when matched then update set dummy=dummy+1
delete where a_value not in ('ace','afk')
when not matched then insert (the_id,a_value)
values (3,e.the_value)
where e.the_value in ('ace','afk');
-- pair ace and aei with id 3
-- should remove afk, add aei, do nothing with ace
merge into paired_value p using every_value e
on ( p.the_id = 3 and p.a_value = e.the_value )
when matched then update set dummy = dummy+1
delete where a_value not in ('ace','aei')
when not matched then insert (the_id,a_value)
values (3,e.the_value)
where e.the_value in ('ace','aei');
-- pair aaa and adg with id 4
merge into paired_value p using every_value e
on ( p.the_id = 4 and p.a_value = e.the_value )
when matched then update set dummy = dummy+1
delete where a_value not in ('aaa','adg')
when not matched then insert (the_id,a_value)
values (4,e.the_value)
where e.the_value in ('aaa','adg');
select * from paired_value;
私はこれをOracle 10gで試しましたが、これで sqlfiddle 、Oracle 11gを試しました。
いいえ、マージコマンドで更新されていない行は削除できません。
ここにドキュメントがあります: http://docs.Oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm
DELETE where_clauseを指定して、データの移入または更新中に表のデータをクリーンアップします。 この句の影響を受ける行は、マージ操作によって更新される宛先テーブルの行のみです。 DELETE WHERE条件は、UPDATE SET ... WHERE条件によって評価された元の値ではなく、更新された値を評価します。宛先テーブルの行がDELETE条件を満たすが、ON句で定義された結合に含まれていない場合、その行は削除されません。ターゲット表で定義された削除トリガーは、行が削除されるたびにアクティブになります。
つまり、行は更新する必要があります。 Hovewer、すべての行を更新する必要はありません。UPDATEの後は、DELETEの後と同じWHERE句を使用します。
when matched then update set dummy=dummy
where a_value not in ('ace','afk')
delete
where a_value not in ('ace','afk')
列をそれ自体に設定できることがわかりました:
MERGE ...
WHEN MATCHED THEN
UPDATE SET a_value = a_value WHERE a_value not in ('ace','afk')
DELETE WHERE a_value not in ('ace','afk')
これにより、ダミー列の必要性がなくなります。