あなたは代わりに、更新のマージを使用することができます。
merge into address a
using (
select k_id, max(k_add) keep (dense_rank last order by chg_dt) as k_add
from add_hist
group by k_id
) h
on (a.k_id = h.k_id)
when matched then
update set a.k_add = h.k_add
where (a.k_add is null and h.k_add is not null)
or (a.k_add is not null and h.k_add is null)
or a.k_add != h.k_add;
using
句のクエリは履歴テーブルから各IDの最新のアドレスを検索します。一致するIDが更新されたメインテーブル上に存在する場合 - 値が異なる場合のみ、where
句のため。いくつかのダミーデータで
:
create table address (k_id number primary key, k_add varchar2(20));
create table add_hist (k_id number, k_add varchar2(20), chg_dt date);
insert into address (k_id, k_add) values (1, 'Address 1');
insert into address (k_id, k_add) values (2, 'Address 2');
insert into address (k_id, k_add) values (3, null);
insert into address (k_id, k_add) values (4, null);
insert into add_hist (k_id, k_add, chg_dt) values (1, 'Address 1', date '2017-01-01');
insert into add_hist (k_id, k_add, chg_dt) values (1, 'Address 2', date '2017-01-02');
insert into add_hist (k_id, k_add, chg_dt) values (1, 'Address 1', date '2017-01-03');
insert into add_hist (k_id, k_add, chg_dt) values (2, 'Address 1', date '2017-01-01');
insert into add_hist (k_id, k_add, chg_dt) values (2, 'Address 2', date '2017-01-02');
insert into add_hist (k_id, k_add, chg_dt) values (2, 'Address 3', date '2017-01-03');
insert into add_hist (k_id, k_add, chg_dt) values (3, 'Address 1', date '2017-01-01');
insert into add_hist (k_id, k_add, chg_dt) values (3, null, date '2017-01-02');
insert into add_hist (k_id, k_add, chg_dt) values (4, 'Address 1', date '2017-01-01');
commit;
あなたの更新ステートメントを実行するには、取得します。
4 rows updated.
select * from address;
K_ID K_ADD
---------- --------------------
1 Address 1
2 Address 3
3
4 Address 1
を開始状態にロールバックした後、マージを取得し実行している:
2 rows merged.
select * from address;
K_ID K_ADD
---------- --------------------
1 Address 1
2 Address 3
3
4 Address 1
同じ最終結果ですが、更新された2行ではなく1行がマージされました。
(where
句を使用せずにマージを実行すると、4つの行はすべて影響を受けますが、nullチェックなしでID 2の行のみが更新されます)。
私が直接あなたの単一の更新文でそのチェックを行う方法を見ていませんよ。最初にkadの出力を(サブクエリから)変数に保存しておき、その値が実際にテーブルにあるものと異なる場合にのみ更新を実行する必要があります。 –
ありがとうRenato :) –
@RenatoAfonso - あなたの将来のためにオラクルのオフィシャルトレーニングセッション:https:// stackoverflow。com/documentation/oracle/8061/update-with-joins#t = 201706230023201170024 – mathguy