a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 88|回复: 0

[综合] Oracle认证辅导:Oracle9i后的Merge语句剖析

[复制链接]
发表于 2012-8-4 13:54:49 | 显示全部楼层 |阅读模式
念头:/ u: V9 L0 [$ i1 f+ T
  想在Oracle赌暌姑一条SQL语句直接进行Insert/Update的操作。1 n! o7 O$ |' q3 r5 o6 B" w
  声名:
0 L4 W+ [0 z4 E$ L- W  在进行SQL语句编写时,我们经常会碰着年夜量的同时进行Insert/Update的语句 ,也就是说当存在记势瘫,就更新(Update),不存在数据时,就插入(Insert)。7 P, s( ~$ I! E' J; U! _/ I% L: j
  拭魅战:
7 m: g2 C3 y! X  接下来我们有一个使命,有一个表T,有两个字段a,b,我们想在表T中做Insert/Update,如不美观存在,则更新T中b的值,如不美观不存在,则插入一标识表记标帜录。在Microsoft的SQL语法中,很简单的一句判定就可以了,SQL Server中的语法如下:3 `. W1 Z4 Q8 R; T6 [/ I4 g1 q
  if exists(select 1 from T where T.a=''1001'' ) update T set T.b=2 Where T.a=''1001'' else insert into T(a,b) values(''1001'',2);
. r% M4 q+ [3 T( H  以上语句剖明当T表中如不美观存在a=''1001'' 的记实的话,就把b的值设为2,否则就Insert一条a=''100'',b=2的记实到T中。3 O, j" {1 @8 O3 }8 U6 O
  可是接下来在Oracle中就碰着麻烦了,记得在Oracle 9i之后就有一条Merge into 的语句可以同时进行Insert 和Update的吗,Merge的语法如下:& X% q! i7 W* _' h9 C
  MERGE INTO table_name alias1& F) v4 }# J. |# y% h
  USING (table|view|sub_query) alias2
- {( N3 \( T4 W. l. r/ f  ON (join condition)
" q- Z; I3 t2 o6 ?" A% g  WHEN MATCHED THEN
% p, r' e9 ?0 F0 e7 u" u2 O* J9 h  UPDATE table_name' [% ^1 f+ u9 _: w# c6 Q& p
  SET col1 = col_val1,
8 Z" C( E8 Y: ~( f$ q  s6 L2 P% N  col2 = col2_val# p! B* U' v- n+ M( [
  WHEN NOT MATCHED THEN* g, G" C" A0 j
  INSERT (column_list) VALUES (column_values);
+ _- B" c( ^( M. L& ^% ^5 n  膳缦沔的语法巨匠应该都轻易懂吧,那我们按照以上的逻辑再写一次。
* E8 ~) a  C6 N9 b5 C  MERGE INTO T T1
" ~+ b. Z: e  ]: ~9 T  USING (SELECT a,b FROM T WHERE t.a=''1001'') T2
- X% W; S8 a$ z  ON ( T1.a=T2.a)
- S; u, ?( y, F' L. }  WHEN MATCHED THEN
8 N2 p8 x& _. T. i( T8 P7 X  UPDATE SET T1.b = 2
% ]" g/ y& j6 _6 n  WHEN NOT MATCHED THEN
+ u6 m7 B' ^- L+ i3 c& p  INSERT (a,b) VALUES(''1001'',2);
9 d, U' f; v3 |) p2 J  以上的语句貌似很对是吧,现实上,该语句只能进行更新,而无法进行Insert,错误在哪里呢?
( d- A' e/ a0 S8 M4 Y- R" f% T  其其实Oracle中Merge语句原先是用来进行整表的更新用的,也就是ETL工具斗劲常用的语法,重点是在Using上。
% L- q6 c1 @) y% r- O- Z& c  用中文来诠释Merge语法,就是:* g& b' `: a1 [0 n
  在alias2中Select出来的数据,每一条都跟alias1进行 ON (join condition)的斗劲,如不美观匹配,就进行更新的操作(Update),如不美观不匹配,就进行插入操作(Insert)。
3 t. J! e! n8 y2 a, }* N, P  是以,严酷意义上讲,”在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记实数,就是Using语句中alias2的记实数。”
0 O+ n: D% q( _+ x; l  以上这句话也就很好的诠释了在膳缦沔写的语句为何只能进行Update,而不能进行Insert了,因为都Select不到数据,若何能进行Insert呢:)7 e- C( \; m3 O9 |9 @, h6 l
  接下来要改成正确的语句就轻易多了,如下:( i- N; T& G/ m2 Z
  MERGE INTO T T1$ }' \' M) V* k0 |
  USING (SELECT ''1001'' AS a,2 AS b FROM dual) T2
( ^$ f6 W# w* e. {+ y; o, ^  ON ( T1.a=T2.a)
8 [8 D7 O; V' I# j  o  X9 h* \5 c6 Z  WHEN MATCHED THEN
! i: y/ J) w5 I4 P  UPDATE SET T1.b = T2.b
8 @' f* g: w! d; y* E% m  WHEN NOT MATCHED THEN( }  f# \- F3 V/ f1 G
  INSERT (a,b) VALUES(T2.a,T2.b);5 `& w+ `( \8 g: ?- g
  发芽结不美观,OK!
- _5 {6 a9 g, j4 x% s9 T  注重:
/ @3 h6 ]0 m+ N! p  如不美观不懂Merge语句的事理,Merge语句是一条斗劲危险的语句,出格是在您只想更新一标识表记标帜录的时辰,因为不经意间,你可能就把整表的数据都Update了一遍.+ c) R& ]4 A, f3 ^) r+ k
  我曾经犯过的一个错误如下所示,巨匠看出来是侍趵硎题了吗?
# q. S1 |; n' {& k9 d+ L  MERGE INTO T T1
/ g4 |; k: p4 p' c$ l  USING (SELECT Count(*) cnt FROM T WHERE T.a=''1001'') T2
# V  z, u- P2 h+ _$ {# C1 v  ON (T2.cnt>0)
& g8 \$ F1 {( S( L" N* n  WHEN MATCHED THEN
/ k3 h/ ^" j* F6 a/ u* ^  UPDATE SET T1.b = T2.b
! x. u* @9 z) S1 r  WHEN NOT MATCHED THEN4 _. O% I* _  J0 L$ I; m. s
  INSERT (a,b) VALUES(T2.a,T2.b);
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-14 16:03 , Processed in 0.174242 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表