在Oracle SQL中执行MERGE时,如何更新SOURCE中不匹配的行?

Sco*_*pey 14 sql oracle sql-merge

我有一个main数据库和report数据库,我需要从同步表mainreport.

但是,当一个项目在main数据库中被删除时,我只想IsDeletedreport数据库中设置一个标志.

这样做的优雅方式是什么?

我目前正在使用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...)
;
Run Code Online (Sandbox Code Playgroud)

WHEN NOT MATCHED语句为我提供了所有新值main,但我也希望更新所有OLD值report.

我正在使用Oracle PL/SQL.

ste*_*rey 16

您可以使用单独的UPDATE语句来完成此操作

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

我不知道有任何方法可以将它集成到MERGE语句中.

  • 非常感谢,这个链接非常有用我学到了什么:如果`MERGE`只有'当匹配那么'时,它会使用常规的`JOIN`.如果有一个"WHEN NOT MATCHED THEN",它会使用"LEFT OUTER JOIN".现在,我希望有一个功能,比如"什么时候不匹配来源",这将做一个"FULL OUTER JOIN".但这可能仅适用于SQL Server,而不适用于Oracle. (4认同)

Jon*_*ler 5

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
Run Code Online (Sandbox Code Playgroud)


Zaf*_*yed 5

下面的答案是将数据合并到同一个表中

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');
Run Code Online (Sandbox Code Playgroud)

此命令检查USER_IDUSER_NAME是否匹配,如果不匹配则插入。