正如其他人所指出的,BY TARGET 可以为 Oracle 删除,它可以按您的预期工作。这里有一个带有两个表的小脚本,它们显示了这种行为并且它有效。您希望将 temp_test 中的所有行合并到 summary 中,这些行在 temp_test 中但尚未在 summary 中。
create table temp_test
(
DT date,
Foobar varchar2(100),
Step varchar2(100)
);
create table summary
(
DT date,
Foobar varchar2(100),
Step varchar2(100),
OtherFields varchar2(100) NULL
);
/
insert into temp_test values (trunc(sysdate), 'test', '20'); -- should be inserted
insert into temp_test values (trunc(sysdate-1), 'test', '20'); -- already in summary
INSERT into summary (DT, Foobar, Step) VALUES (trunc(sysdate-1), 'test', '20');
select * from temp_test; -- 2 records
select * from summary; -- 1 record
merge into summary TARGET
USING temp_test SOURCE
ON (TARGET.DT = SOURCE.DT and TARGET.Foobar = SOURCE.Foobar and TARGET.Step = SOURCE.Step)
WHEN NOT MATCHED THEN
INSERT (DT, Foobar, Step) VALUES (SOURCE.DT, SOURCE.Foobar, SOURCE.Step);
-- 1 row updated
select* from gui_po_summary; -- 2 rows
-- try to merge again, nothing should be done
merge into summary TARGET
USING temp_test SOURCE
ON (TARGET.DT = SOURCE.DT and TARGET.Foobar = SOURCE.Foobar and TARGET.Step = SOURCE.Step)
WHEN NOT MATCHED THEN
INSERT (DT, Foobar, Step) VALUES (SOURCE.DT, SOURCE.Foobar, SOURCE.Step);
-- 0 rows
delete temp_test; -- 2 rows deleted
-- try to merge again, nothing should be done as we want WHEN NOT MATCHED BY target
merge into summary TARGET
USING temp_test SOURCE
ON (TARGET.DT = SOURCE.DT and TARGET.Foobar = SOURCE.Foobar and TARGET.Step = SOURCE.Step)
WHEN NOT MATCHED THEN
INSERT (DT, Foobar, Step) VALUES (SOURCE.DT, SOURCE.Foobar, SOURCE.Step);
-- 0 rows
还有WHEN NOT MATCHED BY source 需要Oracle 特殊处理,并在此处回答https://stackoverflow.com/a/48842932/4040068。