Reputation: 55
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!
Upvotes: 1
Views: 449
Reputation: 17429
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'
Upvotes: 1