在oracle 9i和更高版本中,提供了一个新的函数 merge into。通过它,我们可以实现类似hibernate的saveOrUpdate的方法。
在oracle 10G则进行 了增强,可参考http://tomszrp.itpub.net/post/11835/263865
先介绍下 merge into
[code="java"]MERGE [ hint ]
INTO [ schema. ]table A
USING [ schema. ] { table | view | subquery } B
ON ( condition )
[ merge_update_clause ]
[ merge_insert_clause ] ;
WHEN MATCHED THEN
UPDATE SET column = { expr | DEFAULT }
[, column = { expr | DEFAULT } ]...
[ where_clause ]
[ DELETE where_clause ]
WHEN NOT MATCHED THEN
INSERT [ (column [, column ]...) ]
VALUES ({ expr [, expr ]... | DEFAULT })
[ where_clause ]
WHERE condition
需要注意的地方:
①9i已经支持了,是Merge,但是只支持select子查询,
如果是单条数据记录,可以写作select …… from dual的子查询
②update 中不能出现 on 中的列
③
MERGE INTO T T1 USING (SELECT a,b FROM T WHERE t.a='1001') T2 ON ( T1.a=T2.a) WHEN MATCHED THEN UPDATE SET T1.b = 2 WHEN NOT MATCHED THEN INSERT (a,b) VALUES('1001',2);
其实在Oracle中Merge语句原先是用来进行整表的更新用的,也就是ETL工具比较常用的语法,重点是在Using上。
用中文来解释Merge语法,就是:在B中Select出来的数据,每一条都跟A进行 ON (join condition)的比较,如果匹配,就进行更新的操作(Update),如果不匹配,就进行插入操作(Insert)。
因此,严格意义上讲,"在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记录数,就是Using语句中B的记录数。"
以上这句话也就很好的解释了在上面写的语句为何只能进行Update,而不能进行Insert了,因为都Select不到数据,如何能进行Insert呢:)
下面就是自己程序中实际的例子中语句:
MERGE INTO dl_fpgydfx A USING (SELECT '2011-12-26' AS a,545 AS b ,545 AS c,545 AS d,545 AS e,'gc' AS f,'all' AS g FROM dual) B ON ( A.RQ=B.a and A.BM=B.f and A.SBDM=B.g) WHEN MATCHED THEN UPDATE set A.FENG=900 WHEN NOT MATCHED THEN INSERT VALUES ('2011-12-26',545,332,522,241,'gc','all')
该语句实现的是对于'2011-12-26',545,332,522,241,'gc','all'记录 判断在dl_fpgydfx 中是否存在,存在则update,不存在则进行插入操作。
若进行批量更新,则需要将要更新的记录放到B表里面,然后就可以实现批量更新了。
参考文章:
http://space.itpub.net/559237/viewspace-402876