I encountered a problem with Oracle's MERGE DML yesterday.  What I was trying to do is use the "Upsert" feature of the merge, except with no distinct source.  All of the searching I did for the MERGE showed examples of how to merge data from a source into a target.  In my case, I thought the source and the target were the same.

This is what I initially tried.  It didn't work.  It turns out that if the source (s) returns an empty set, then the merge is effectively a no-op

   1: merge into MY_TARGET t
   2: using (select *
   3:          from MY_TARGET
   4:         where COL1 = :p1
   5:           and COL2 = :p2) s
   6:   on (t.COL1 = s.COL1 
   7:   and t.COL2 = s.COL2)
   8: when matched then
   9:   update set t.COL3 = :p3
  10: when not matched then
  11:   insert (COL1, COL2, COL3) 
  12:   values (:p1, :p2, :p3)

I thought for a while to figure out how I could get the source to always return something.  Finally it occurred to me that I could use DUAL.

   1: merge into MY_TARGET t
   2: using (select 1 from DUAL) s
   3:   on (t.COL1 = :p1 
   4:   and t.COL2 = :p2)
   5: when matched then
   6:   update set t.COL3 = :p3
   7: when not matched then
   8:   insert (COL1, COL2, COL3) 
   9:   values (:p1, :p2, :p3)

I hope this helps someone else.  At the very least it will be here the next time I need it.

Tags: , ,
posted on Wednesday, March 05, 2008 12:53 AM
Filed Under [ Oracle Database ]

Comments

Gravatar
# re: Oracle Merge To Self
posted by tytang
on 5/6/2008 8:53 PM
Thanks.. you helped me alot
Gravatar
# re: Oracle Merge To Self
posted by sam
on 6/27/2008 1:05 AM
awesome!!!! i has similar issue, cracked my head for 3 hours, search the web, nothing!!
bam! finally saw your post, tried it, worked like a charm...

Thanks a million.

sam
Gravatar
# re: Oracle Merge To Self
posted by Will Smith
on 6/28/2008 7:58 PM
I'm glad to have helped you guys!
Gravatar
# re: Oracle Merge To Self
posted by Mehmet Özakan
on 1/5/2009 6:05 AM
The case of empty source(s) did not mentioned on the web. I got the same error with you. Your way to do it, is great.

Moreover, when your target and source is the same table, you can just use " using (t.COL1 = :p1 and t.COL2 = :p2) " syntax.

Thanks for sharing your best practices ...
Gravatar
# re: Oracle Merge To Self
posted by Dee
on 1/19/2009 8:35 AM
Thank You. this is exactly what I needed and it was a BIG help to me.
Gravatar
# re: Oracle Merge To Self
posted by gcuevas
on 8/10/2009 8:50 PM
I'm trying to do something similar with bound variables and not having much luck.

MERGE INTO myTarget h
USING (SELECT 1 FROM dual) s
ON (h.H3=:h3)
WHEN MATCHED THEN UPDATE
SET h.H4=:h4, h.H5=:h5
WHEN NOT MATCHED THEN INSERT (h.h3, h.h4, h.h5)
VALUES (:h3,:h4,:h5);

Thoughts?
Gravatar
# re: Oracle Merge To Self
posted by Will
on 8/20/2009 10:26 AM
@gcuevas

What kind of error are you getting?

I can't see any problems with the syntax.
Gravatar
# re: Oracle Merge To Self
posted by summerian
on 9/29/2009 11:08 AM
Thank you very much for this post :)
Gravatar
# re: Oracle Merge To Self
posted by Mahim
on 9/30/2009 3:23 PM
Thanks - I was stuck with this problem and your article helped me out .. thanks for sharing this.
Gravatar
# re: Oracle Merge To Self
posted by aditya
on 10/12/2009 5:35 PM
Thanks. Just what I was looking for!
Gravatar
# re: Oracle Merge To Self
posted by Patrick
on 10/23/2009 9:47 AM
GREAT WORK!!! Oracle documentation sucks big time. I could not find anything like this on the Oracle site.

Thank you for posting!!

Regards,
Patrick
MTR Investors Group
www.MTRIG.com

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: