我有一个可以通过oracle数据库链接访问的表,我试图将其拉入本地数据库表,原因很简单。
MERGE INTO MEMBERSHIPS LOCAL
USING (
SELECT DISTINCT
REMOTE.GROUP_NAME "GROUP_NAME",
REMOTE.USER_ACCOUNT "USERNAME",
REMOTE.SOME_OTHER_COLUMN "COL3"
FROM MEMBERSHIPS@link REMOTE
) REMOTE
ON (
REMOTE.GROUP_NAME = LOCAL.GROUP_NAME AND
REMOTE.USERNAME = LOCAL.USERNAME
)
WHEN MATCHED THEN
UPDATE SET
LOCAL.COL3 = REMOTE.COL3
LOCAL.UPDATED_AT = sysdate
WHEN NOT MATCHED THEN
INSERT (ID, GROUP_NAME, USERNAME, COl3, CREATED_AT, UPDATED_AT)
VALUES (MEMBERSHIPS_SEQ.NEXTVAL, REMOTE.GROUP_NAME, REMOTE.USERNAME, REMOTE.COl3, sysdate, sysdate)
最不幸的是,原始数据库的所有者并没有因担心数据完整性而失去多少睡眠,所以在300万行中,有71个重复,这会炸毁我的组名,用户名上的唯一索引。如果我删除唯一性约束,合并将处理,但是这些行将随后在ORA-30926: unable to get a stable set of rows in the source tables
的查询执行中爆炸。
这是每天都会运行的东西,所以我需要找到一种方法来忽略重复
编辑:
我原以为不同的人会为我解决这个问题,但事实并非如此。我仍然得到重复:
SELECT DISTINCT
REMOTE.GROUP_NAME,
REMOTE.USER_ACCOUNT
COUNT(*)
FROM MEMBERSHIPS@link REMOTE
GROUP BY
REMOTE.GROUP_NAME,
REMOTE.USER_ACCOUNT
HAVING COUNT(*) > 1;
显示仍有重复的71个GROUP_NAME / USER_ACCOUNT个组合
答案 0 :(得分:2)
在类似情况下,您始终可以尝试对行进行排名以避免重复,而不是DISTINCT。 在这种情况下,它会是这样的:
MERGE INTO MEMBERSHIPS LOCAL
USING (
SELECT rank() over(partition by REMOTE.GROUP_NAME
,REMOTE.USER_ACCOUNT
order by NVL(REMOTE.UPDATED_AT,REMOTE.CREATED_AT) DESC NULLS LAST) r,
REMOTE.GROUP_NAME "GROUP_NAME",
REMOTE.USER_ACCOUNT "USERNAME",
REMOTE.SOME_OTHER_COLUMN "COL3"`
FROM MEMBERSHIPS@link REMOTE ) REMOTE
ON (
REMOTE.GROUP_NAME = LOCAL.GROUP_NAME
AND REMOTE.USERNAME = LOCAL.USERNAME
AND REMOTE.r = 1
)
WHEN MATCHED THEN
UPDATE SET
LOCAL.COL3 = REMOTE.COL3
LOCAL.UPDATED_AT = sysdate
WHEN NOT MATCHED THEN
INSERT (ID, GROUP_NAME, USERNAME, COl3, CREATED_AT, UPDATED_AT)
VALUES (MEMBERSHIPS_SEQ.NEXTVAL, REMOTE.GROUP_NAME, REMOTE.USERNAME, REMOTE.COl3, sysdate, sysdate);
答案 1 :(得分:1)
我尝试使用两个本地表重现您描述的问题。通过您提供的合并,我没有源表中的重复项引起的问题(在Oracle 11.2.0.4中)。如果我从DISTINCT
子句中的子查询中删除USING
关键字,那么我会得到您所描述的问题 - 第一次尝试时出现约束违规,或者如果我删除则会出现第二次尝试中的ORA-30926独特的约束。
我能想到的两个解释是:(a)您在Oracle中遇到了一些错误,可能涉及远程子查询中的DISTINCT,或者(b)您实际运行的合并语句不包括{ {1}}。 (我还考虑过NULL值可能导致DISTINCT操作出现意外结果的可能性,但我无法想出会发生的方法。)
编辑: 另一个经过深思熟虑的解释 - 如果两个数据库使用不同的字符集,我想知道原始表中不同的值是否可能在传输中转换为相同的值?