Skip to Main Content
  • Questions
  • Unique Constraint violation when using merge

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Wolfgang.

Asked: September 17, 2008 - 3:15 pm UTC

Last updated: September 22, 2008 - 4:58 pm UTC

Version: 10.2.0.3

Viewed 10K+ times! This question is

You Asked

Hi Tom,

we are using external tables to load an update our tables. Because of an error in one of our mainframe programs we got dublicate rows in the file we wanted to merge.
The result was a Unique Constraint violation on the PK constraint.

Here is a little test case:
create table dest 
(id number primary key,
 col1 varchar2(10));

create table src
(id number,
 col1 varchar2(10));

insert into src values(1,'ABC');
insert into src values(2,'GHB');
insert into src values(3,'DUP');
insert into src values(3,'DUP');

commit;

merge into dest 
  using 
  (select id,col1 from src) src on(dest.id=src.id)
when not matched then 
  insert values(src.id,src.col1)
when matched 
  then update set dest.col1=src.col1;


Why does this happen? In my understanding the merge should first insert the row and then update the existing row.

Regards
Wolfgang

and Tom said...

it would be non-deterministic if it did that.

That is, given the same set of input data - we could come up with different "answers" depending on how the rows were accidentally processed.

One day we might insert "row A" and then update it with "row B"

Next day we might insert "row B" and then update it with "row A"

same inputs exactly, different answers.


Merge uses read consistency to process, the set of rows that can be modified is "set in stone" as of the time the statement begins processing.


You would need to use distinct on the "using" set of data in this case.

Rating

  (5 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Wolfgang Bauer, September 18, 2008 - 3:15 pm UTC

Thanks for your answer Tom.
Is there any documentation available how merge works internally? E.g. why it doews not work with text indexes (at least if you don't use 11g).

Regards
Wolfgang


Tom Kyte
September 18, 2008 - 9:51 pm UTC

I don't know how knowing the "internals" of merge would be useful here?

It was not supported in 10g and before to merge into a table with a domain index, in 11g - that functionality is now supported.

Determinism

Duke Ganote, September 18, 2008 - 3:22 pm UTC

Certainly I also initially assumed that MERGE would process the USING rows in some order, but the documentation is clear:
"MERGE is a deterministic statement. That is, you cannot update the same row of the target table multiple times in the same MERGE statement"

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5318183934935#52657699523363

http://68.142.116.70/docs/cd/B19306_01/server.102/b14200/statements_9016.htm#SQLRF01606

Wolfgang Bauer, September 20, 2008 - 11:44 am UTC

Tom,
my question about "internal" documentation has nothing to do with the original question - after your answer it is clear to me why the ORA-00001 happends.

It was just asking for vested interest.

Regards
Wolfgang
Tom Kyte
September 21, 2008 - 1:51 pm UTC

but all DML is done that way... It is nothing specific to merge. There is always a read component - done with read consistency to find the rows to modify, there is always a write component - to modify the rows - whereby the read consistent data is compared to the current version (eg: the cause of a restart, but this isn't internal or anything, it is documented, this is my write up of it)

http://asktom.oracle.com/Misc/something-different-part-i-of-iii.html
http://asktom.oracle.com/Misc/part-ii-seeing-restart.html
http://asktom.oracle.com/Misc/part-iii-why-is-restart-important-to.html

you should use distinct

Yonglei, September 21, 2008 - 5:39 pm UTC

Merge can't handle duplicate rows, you need to add distinct on source table:

(select distinct id,col1 from src) src



Tom Kyte
September 22, 2008 - 4:58 pm UTC

adding distinct would be an obvious approach (remove the duplicates) - but would not have "answered" the question.

the question was "why"

This was very useful - Thank you.

suzanne weiss, October 11, 2012 - 6:53 pm UTC

We have a third party file that we've processed with a MERGE in the past. The most recent file had duplicate entries. The very first question in this thread asked the question I was trying to answer. Thank you. The answer that you gave very clearly answered all of my questions. We'll now go request a cleared up file.

More to Explore

Security

All of the vital components for a secure database are covered in the Security guide.