问题
I inherited an Oracle script running on Oracle 11g that contains the following MERGE statement:
MERGE INTO MainTable PR
USING IncrementalTable PRA
ON (PR.contract = PRA.contract
and PRA.memberType = 'Parent' )
WHEN MATCHED THEN
UPDATE SET PR.address1 = PRA.address1,
PR.city = PRA.city,
PR.state = PRA.sate,
PR.zipCode = PRA.zipCode,
PR.countryCode = PRA.countryCode
WHERE address1 IS NULL
AND PR.memberType <> 'Parent'
;
As far as I can see, this is simply updating the child's address in MainTable from the parent's address in IncrementalTable. Unfortunately, when I run the statement, it throws the following error:
ORA-30926: unable to get a stable set of rows in the source tables
So, it looks like it can't find a distinct match in IncrementalTable with which to update. Querying the data, that appears to be the case:
select contract,
memberType,
count(*)
from IncrementalTable
group by contract,
memberType
having count(*) > 1
;
CONTRACT MEMBERTYPE COUNT(*)
---------------------- ---------- ----------
1119839490 PARENT 2
7271122516 PARENT 2
1004798721 PARENT 2
Looking at the details of one of those contracts:
select *
from IncrementalTable
where contract = '1119839490'
and memberType = 'Parent'
;
CONTRACT MEMBERTYPE ADDRESS1 CITY STATE ZIPCODE COUNTRYCODE
---------------------- ---------- ---------------- ------------------------------ ----- ------- -----------
1165439488 Parent 1234 Dorioth St Orlando FL 32825 USA
1165439488 Parent 1234 Dorioth St Orlando FL 32825 USA
So, how can I merge only the DISTINCT match from IncrementalTable?
Thanks in adavnce for your help!
回答1:
The first (and most obvious) answer is to clean up the data so you don't have duplicates. It seems likely that the sample data you provided is the result of a bug.
As for the merge
statement, if the data is actually purely duplicated, you can just use distinct
:
MERGE INTO maintable pr
USING (SELECT DISTINCT contract,
membertype,
address1,
city,
state,
zipcode,
countrycode
FROM incrementaltable pra
WHERE pra.membertype = 'Parent')
ON (pr.contract = pra.contract)
WHEN MATCHED THEN
UPDATE SET pr.address1 = pra.address1,
pr.city = pra.city,
pr.state = pra.sate,
pr.zipcode = pra.zipcode,
pr.countrycode = pra.countrycode
WHERE address1 IS NULL AND pr.membertype <> 'Parent'
来源:https://stackoverflow.com/questions/28636860/oracle-merge-statement-error-ora-30926