问题描述
sql> SELECT * FROM SOURCE;
MEMBER_ID FirsT_NAME LAST_NAME RANK
---------- ---------- ---------- --------------------
1 Abel Wolf Gold
2 Clarita Franco Platinum
3 Darryl Giles Silver
4 Dorthea Suarez Silver
5 Katrina Wheeler Silver
6 Lilian Garza Silver
7 Ossie Summers Gold
8 Paige Mcfarland Platinum
9 Ronna Britt Platinum
10 Tressie Short bronze
10 rows selected.
sql> SELECT * FROM DESTINATION;
MEMBER_ID FirsT_NAME LAST_NAME RANK
---------- ---------- ---------- --------------------
1 Abel Wolf Silver
2 Clarita Franco Platinum
3 Darryl Giles bronze
4 Dorthea Gate Gold
5 Katrina Wheeler Silver
6 Lilian Stark Silver
11 Chris Well Silver
7 rows selected.
当我尝试执行以下查询时,它正在执行,但未从目标表中删除记录11:
MERGE INTO DESTINATION D
USING SOURCE S
ON (D.MEMBER_ID = S.MEMBER_ID)
WHEN MATCHED THEN
UPDATE
SET D.FirsT_NAME = S.FirsT_NAME,D.LAST_NAME = S.LAST_NAME,D.RANK = S.RANK
DELETE
WHERE D.MEMBER_ID <> S.MEMBER_ID
WHEN NOT MATCHED THEN
INSERT
(D.MEMBER_ID,D.FirsT_NAME,D.LAST_NAME,D.RANK)
VALUES
(S.MEMBER_ID,S.FirsT_NAME,S.LAST_NAME,S.RANK);
解决方法
因为当前逻辑隐式使用INNER JOIN
,并且表MEMBER_ID = 11
中不存在SOURCE
,所以该值不会引起MATCHED
的情况,因此永远不会已被删除。
您可以如下使用OUTER JOIN
之类的FULL JOIN
MERGE INTO DESTINATION D
USING (SELECT NVL(S.MEMBER_ID,D.MEMBER_ID) AS MEMBER_ID,S.FIRST_NAME,S.LAST_NAME,S.RANK
FROM DESTINATION D
FULL JOIN SOURCE S
ON S.MEMBER_ID = D.MEMBER_ID) S
ON (NVL(S.MEMBER_ID,D.MEMBER_ID) = D.MEMBER_ID)
WHEN MATCHED THEN
UPDATE
SET D.FIRST_NAME = S.FIRST_NAME,D.LAST_NAME = S.LAST_NAME,D.RANK = S.RANK
DELETE
WHERE S.FIRST_NAME IS NULL
WHEN NOT MATCHED THEN
INSERT
(D.MEMBER_ID,D.FIRST_NAME,D.LAST_NAME,D.RANK)
VALUES
(S.MEMBER_ID,S.RANK);