web-dev-qa-db-ja.com

Oracle SQLでMERGEを実行する場合、SOURCEで一致しない行を更新するにはどうすればよいですか?

mainデータベースとreportデータベースがあり、mainからreportにテーブルを同期する必要があります。

ただし、mainデータベースでアイテムが削除された場合は、IsDeletedデータベースでreportフラグのみを設定します。

これを行うエレガントな方法は何ですか?

現在、次のようなMERGEステートメントを使用しています。

MERGE INTO report.TEST target
USING (SELECT * FROM main.TEST) source
   ON (target.ID = source.ID)
WHEN MATCHED THEN
    UPDATE SET (target... = source...)
WHEN NOT MATCHED THEN
    INSERT (...) VALUES (source...)
;

WHEN NOT MATCHEDステートメントはmainからのすべての新しい値を提供しますが、reportからのすべてのOLD値も更新します。

Oracle PL/SQLを使用しています。

13
Scott Rippey

別のUPDATEステートメントでそれを行うことができます

UPDATE report.TEST target
SET    is Deleted = 'Y'
WHERE  NOT EXISTS (SELECT 1
                   FROM   main.TEST source
                   WHERE  source.ID = target.ID);

これをMERGEステートメントに統合する方法がわかりません。

14
steve godfrey
MERGE INTO target
USING
(
    --Source data
    SELECT id, some_value, 0 deleteMe FROM source
    --And anything that has been deleted from the source
    UNION ALL
    SELECT id, null some_value, 1 deleteMe
    FROM
    (
        SELECT id FROM target
        MINUS
        SELECT id FROM source
    )
) source
   ON (target.ID = source.ID)
WHEN MATCHED THEN
    --Requires a lot of ugly CASE statements, to prevent updating deleted data
    UPDATE SET target.some_value =
        CASE WHEN deleteMe=1 THEN target.some_value ELSE source.some_value end
    ,isDeleted = deleteMe
WHEN NOT MATCHED THEN
    INSERT (id, some_value, isDeleted) VALUES (source.id, source.some_value, 0)

--Test data
create table target as
select 1 ID, 'old value 1' some_value, 0 isDeleted from dual union all
select 2 ID, 'old value 2' some_value, 0 isDeleted from dual;

create table source as
select 1 ID, 'new value 1' some_value, 0 isDeleted from dual union all
select 3 ID, 'new value 3' some_value, 0 isDeleted from dual;


--Results:
select * from target;

ID  SOME_VALUE   ISDELETED
1   new value 1  0
2   old value 2  1
3   new value 3  0
5
Jon Heller

次の答えは、データを同じテーブルにマージする

MERGE INTO YOUR_TABLE d
USING (SELECT 1 FROM DUAL) m
    ON ( d.USER_ID = '123' AND d.USER_NAME= 'itszaif') 
WHEN NOT MATCHED THEN
        INSERT ( d.USERS_ID, d.USER_NAME)
        VALUES ('123','itszaif');

このコマンドは、USER_IDおよびUSER_NAMEは一致しますが、一致しない場合は挿入されます。

4
Zafrullah Syed
merge into x as target using y as Source on target.ID = Source.ID
when not matched by target then insert
when matched then update
when not matched by source and target.ID is not null then
update whatevercolumn = 'isdeleted' ;
0
Mark