ORACLE 关连更新 update select
总结: 关键的地方是where 语句的加入. 在11G中, 如果不加11G , 或造成除匹配的行数更新为相应的值之后, 其余的会变成负数.
所以, 测试的办法就是: 先查看需要更新的数量即连接的数量究竟有多少行, 然后update 之后多少行, 才能确定条件是否正确.
引入知识比较全面的地址:
本人用到的2处SQL:
1 :
UPDATE SFISM4.R_DT_DIP_TRACEABILITY_T B
SET (B.CURRENT_QTY, B.UPDATE_TIME, B.UPDATE_USER)=
(SELECT DECODE(SIGN(B.CURRENT_QTY - A.KP_COUNT),
-1,
0,
B.CURRENT_QTY - A.KP_COUNT),
SYSDATE,
:VUSER
FROM SFIS1.C_DT_DIP_BOM_T A, SFISM4.R_MO_BASE_T C
WHERE A.BOM_NO = B.BOM_NO
AND B.BOM_NO = C.KEY_PART_NO
AND A.KEY_PART_NO = B.KEY_PART_NO
AND C.MO_NUMBER =:VBOM
AND B.TRAC_LOT =:VTRACELOT)
WHERE B.TRAC_LOT =:VTRACELOT
AND EXISTS (SELECT 1
FROM SFIS1.C_DT_DIP_BOM_T AA
WHERE B.BOM_NO = AA.BOM_NO
AND B.KEY_PART_NO = AA.KEY_PART_NO)
UPDATE SFISM4.R_REEL_TRACKING_T A
SET A.REMAIN_QTY =
(SELECT B.REEL_QTY
FROM SFISM4.R_MMS_STOCK_SMT_SA_DETAIL_T B
WHERE A.REEL_ID = B.REEL_ID
AND A.REMAIN_QTY <0
AND A.REMAIN_QTY <> B.REEL_QTY)
WHERE EXISTS (SELECT 1
FROM SFISM4.R_MMS_STOCK_SMT_SA_DETAIL_T B
WHERE A.REEL_ID = B.REEL_ID
AND A.REMAIN_QTY <0
AND A.REMAIN_QTY <> B.REEL_QTY);
UPDATE SFISM4.R_REEL_TRACKING_T A
SET A.REMAIN_QTY =
(SELECT B.REEL_QTY
FROM SFISM4.R_MMS_STOCK_SMT_SA_DETAIL_T B
WHERE A.REEL_ID = B.REEL_ID
AND A.REMAIN_QTY <0
AND A.REMAIN_QTY <> B.REEL_QTY)
WHERE EXISTS (SELECT 1
FROM SFISM4.R_MMS_STOCK_SMT_SA_DETAIL_T B
WHERE A.REEL_ID = B.REEL_ID
AND A.REMAIN_QTY <0
AND A.REMAIN_QTY <> B.REEL_QTY);
SQL> select * from wwm2; --要更新的表 , 多一点.
-------------------- ----------
222 222
111 111
ww‘jj 111
llll 1111
dddd 2222
lllldf 111
lllldf 111
dsafdf 111
3435 111
ljjjjj 222
dsafdf 111
-------------------- ----------
3435 111
ljjjjj 222
SQL> select * from wwm5; --更新的条件表 , 少一点
-------------------- ----------
lllldf 111
test 9984
2 /
-------------------- ----------
111 111
ww‘jj 111
lllldf 111
lllldf 111
dsafdf 111
3435 111
dsafdf 111
3435 111
SQL> update wwm2 set wwm2.town=(select wwm5.town from wwm5 where wwm5.id=wwm2.id)
2 /
-------------------- ----------
222
lllldf 111
lllldf 111
1111
2222
lllldf 111
lllldf 111
lllldf 111
lllldf 111
222
lllldf 111
-------------------- ----------
lllldf 111
222
13 rows selected.
SQL> update wwm2
2 set town=(select town from wwm5 where wwm5.id=wwm2.id)
3 where id=(select wwm5.id from wwm5 where wwm5.id=wwm2.id)
4 /
SQL> update wwm2
set town=(select town from wwm5 where wwm5.id=wwm2.id)
where exists (select 1 from wwm5 where wwm5.id=wwm2.id)
8 rows updated.
SQL> update (select a.town atown,a.id aid,b.town btown,b.id bid from wwm2 a,wwm5 b where a.id=b.id)
2 set atown=btown
3 /
set atown=btown
*
ERROR at line 2:
ORA-01779: cannot modify a column which maps to a non key-preserved table
SQL> /
2* set atown=btown
SQL> /
1 declare
2 cursor cur_wwm is select town,id from wwm5; -- 驱动 表
3 begin
4 for my_wwm in cur_wwm loop
5 update wwm2 set town=my_wwm.town -- 被驱动表.
6 where id=my_wwm.id;
7 end loop;
8* end;
SQL> /
-------------------- ----------
222 222
lllldf 111
lllldf 111
llll 1111
dddd 2222
lllldf 111
lllldf 111
lllldf 111
lllldf 111
ljjjjj 222
lllldf 111
-------------------- ----------
lllldf 111
ljjjjj 222
1 merge into wwm2
2 using (select town,id from wwm5) b
3 on (wwm2.id=b.id)
4 when matched then update set town=b.town
5* when not matched then insert (town,id) values (null,null)
SQL> /
-------------------- ----------
---注意这个地方,被插入了一个空值.因为WWM5的ID=9984在WWM2中不能匹配,根本原因是ORACLE9必须有WHEN NOT MATCHED子句,但是ORACLE10可以不许要,也就是ORACLE10可以不写WHEN NOT MATCHED ,就不必插入NULL值了,为解决这个问题,下一步会DELETE WWM5的ID=9984,这样一来就不会执行WHEN NOT MATCHED
222 222
lllldf 111
lllldf 111
llll 1111
dddd 2222
lllldf 111
lllldf 111
lllldf 111
lllldf 111
ljjjjj 222
-------------------- ----------
lllldf 111
lllldf 111
ljjjjj 222
SQL> 2 using (select town,id from wwm5) b
SQL> 3 on (wwm2.id=b.id)
SQL> 4 when matched then update set town=b.town
SQL> 5* when not matched then insert (town,id) values (null,null)
SQL> /
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。