Oracle 中用一個表的數據更新另一個表的數據
最好的方法是用merge語法:
- merge into tab1
- using tab2
- on(tab1.id=tab2.id)
- when matched then
- update set tab1.val = tab2.val
同樣,如果tab2中有多條對應tab1中一條的情況會出錯:ORA-30926: unable to get a stable set of rows in the source tables
比如在tab2中再插入一條 insert into tab2 values(2,'xxxx')
可以通過在using中的subquery中將重復記錄過濾來避免這種錯誤,
merge:
- merge into tab1
- using (select * FROM tab2 X WHERE X.ROWID =
- (SELECT MAX(Y.ROWID) FROM tab2 Y WHERE X.ID = Y.ID)) tab2
- on(tab1.id=tab2.id)
- when matched then
- update set tab1.val = tab2.val
但是考慮到關聯查詢效率問題,可以使用oracle分析函數去重后merge
MERGE INTO YTRPT.T_EXP_CHECK_STATION P
USING (SELECT ORG_CODE, WAYBILL_NO
FROM (SELECT K.ORG_CODE,
K.WAYBILL_NO,
ROW_NUMBER() OVER(PARTITION BY K.WAYBILL_NO ORDER BY K.CREATE_TIME DESC) AS RW --去除重復取出最新的那條記錄,否則merge會出錯
FROM YTEXP.T_EXP_OP_RECORD_HANDON K
WHERE K.CREATE_TIME >= P_START_TIME
AND K.CREATE_TIME < P_END_TIME + 10
AND K.OP_CODE IN ('710', '711') --派件掃描
AND K.STATUS > 0
AND K.AUX_OP_CODE <> 'DELETE')
WHERE RW = 1) TEMP
ON (P.WAYBILL_NO = TEMP.WAYBILL_NO AND P.RPT_DATE = P_START_TIME)
WHEN MATCHED THEN
UPDATE SET P.SIG_ORG_CODE = TEMP.ORG_CODE;