Oracle基礎(chǔ)教程之Merge into
Merge into語句是Oracle9i新增的語法,用來合并UPDATE和INSERT語句。
通過MERGE語句,根據(jù)一張表或多表聯(lián)合查詢的連接條件對另外一張表進(jìn)行查詢,連接條件匹配上的進(jìn)行UPDATE,無法匹配的執(zhí)行INSERT。
這個(gè)語法僅需要一次全表掃描就完成了全部工作,執(zhí)行效率要高于INSERT+UPDATE。通過這個(gè)MERGE你能夠在一個(gè)SQL語句中對一個(gè)表同時(shí)執(zhí)行INSERT和UPDATE操作. 在 Oracle 10g中MERGE有一些新特性,后面我會(huì)介紹這些新特征。先看看MERGE語法如下:
- MERGE INTO TEST_NEW DM USING
- (
- SELECT DATE_CD,
- HR_CD,
- DATE_HR,
- DECODE(GROUPING(CITY_ID), 1, 9999, CITY_ID) AS CITY_ID,
- DECODE(GROUPING(SYSTEM_ID), 1, -9999, SYSTEM_ID) AS SYSTEM_ID,
- SUM(GSM_REG_USERCNT) AS GSM_REG_USERCNT,
- SUM(TD_REG_USERCNT) AS TD_REG_USERCNT,
- SUM(TD_REG_USERRAT) AS TD_REG_USERRAT,
- SUM(GSM_POWERON_USERCNT) AS GSM_POWERON_USERCNT,
- SUM(TD_POWERON_USERCNT) AS TD_POWERON_USERCNT,
- SUM(TD_POWERON_USERRAT) AS TD_POWERON_USERRAT
- FROM TEST_OLD
- GROUP BY DATE_HR, DATE_CD, HR_CD, ROLLUP(SYSTEM_ID),ROLLUP(CITY_ID)
- ) TMP
- ON
- (
- DM.DATE_CD = TMP.DATE_CD
- AND DM.HR_CD = TMP.HR_CD
- AND DM.CITY_ID = TMP.CITY_ID
- AND DM.SYSTEM_ID = TMP.SYSTEM_ID
- )
- WHEN MATCHED THEN UPDATE SET
- DM.GSM_REG_USERCNT = TMP.GSM_REG_USERCNT,
- DM.TD_REG_USERCNT = TMP.TD_REG_USERCNT,
- DM.TD_REG_USERRAT = TMP.TD_REG_USERRAT,
- DM.GSM_POWERON_USERCNT = TMP.GSM_POWERON_USERCNT,
- DM.TD_POWERON_USERCNT = TMP.TD_POWERON_USERCNT,
- DM.TD_POWERON_USERRAT = TMP.TD_POWERON_USERRAT,
- DM.DATE_HR = TMP.DATE_HR
- WHEN NOT MATCHED THEN
- INSERT
- (
- DM.DATE_CD,
- DM.HR_CD,
- DM.DATE_HR,
- DM.CITY_ID,
- DM.SYSTEM_ID,
- DM.GSM_REG_USERCNT,
- DM.TD_REG_USERCNT,
- DM.TD_REG_USERRAT,
- DM.GSM_POWERON_USERCNT,
- DM.TD_POWERON_USERCNT,
- DM.TD_POWERON_USERRAT
- )
- VALUES
- (
- TMP.DATE_CD,
- TMP.HR_CD,
- TMP.DATE_HR,
- TMP.CITY_ID,
- TMP.SYSTEM_ID,
- TMP.GSM_REG_USERCNT,
- TMP.TD_REG_USERCNT,
- TMP.TD_REG_USERRAT,
- TMP.GSM_POWERON_USERCNT,
- TMP.TD_POWERON_USERCNT,
- TMP.TD_POWERON_USERRAT);
WHEN MATCHED THEN UPDATE SET 表示當(dāng)on里面的關(guān)鍵字匹配上的時(shí)候,就進(jìn)行修改操作。
但是值得注意的是,在做修改操作的時(shí)候,不可以修改on里面關(guān)鍵字的值。
WHEN NOT MATCHED THEN INSERT 表示當(dāng)on里面的關(guān)鍵字匹配不上的時(shí)候,也就是說沒有這樣一條記錄存在TEST_NEW表中時(shí),就進(jìn)行新增操作。
這時(shí),做新增操作,就可以將on里面的字段進(jìn)行設(shè)置值。
在ORACLE 10i中,MERGE有如下一些新特性。
1、UPDATE或INSERT子句是可選的
假如某個(gè)系統(tǒng)中,有個(gè)訂單表,現(xiàn)在要求新增訂單的記錄都要反應(yīng)到訂單歷史表ORDER_HISTORY中,我們可以如下寫腳本:
- MERGE INTO ORDER_HISTORY H USING
- (
- SELECT ORDER_ID ,--訂單編號
- CUSTOMER_ID ,--客戶編號
- EMPLOYEE_ID ,--員工編號
- ORDER_DATE ,--訂購日期;
- REQUIRED_DATE ,--預(yù)計(jì)到達(dá)日期
- SHIPPED_DATE ,--發(fā)貨日期
- SHIPPER ,--運(yùn)貨商
- FREIGHT ,--運(yùn)費(fèi)
- SHIP_NAM ,--貨主姓名;
- SHIP_ADDRESS ,--貨主地址
- SHIP_CITY ,--貨主所在城市;
- SHIP_REGION ,--貨主所在地區(qū);
- SHIP_POSTALCODE ,--貨主郵編
- SHIP_COUNTRY --貨主所在國家
- FROM ORDER_DTL
- WHERE TO_CHAR(ODER_DATE, 'YYYY-MM-DD') = '20110530'
- ) O
- ON
- (
- O.ORDER_ID = H.ORDER_ID
- )
- WHEN NOT MATCHED THEN INSERT
- (
- H.ORDER_ID ,
- H.CUSTOMER_ID ,
- H.EMPLOYEE_ID ,
- H.ORDER_DATE ,
- H.REQUIRED_DATE ,
- H.SHIPPED_DATE ,
- H.SHIPPER ,
- H.FREIGHT ,
- H.SHIP_NAM ,
- H.SHIP_ADDRESS ,
- H.SHIP_CITY ,
- H.SHIP_REGION ,
- H.SHIP_POSTALCODE ,
- H.SHIP_COUNTRY
- )
- VALUES
- (
- O.ORDER_ID ,
- O.CUSTOMER_ID ,
- O.EMPLOYEE_ID ,
- O.ORDER_DATE ,
- O.REQUIRED_DATE ,
- O.SHIPPED_DATE ,
- O.SHIPPER ,
- O.FREIGHT ,
- O.SHIP_NAM ,
- O.SHIP_ADDRESS ,
- O.SHIP_CITY ,
- O.SHIP_REGION ,
- O.SHIP_POSTALCODE ,
- O.SHIP_COUNTRY<br>);
從上可以看出,MATCHED 或NOT MATCHED是可選的。不必非得
- WHEN NOT MATCHED THEN UPDATE SET
- .....
- WHEN MATCHED THEN INSERT
2、UPDATE和INSERT子句可以加WHERE子句
現(xiàn)在由于需求改變,我們僅僅需要把員工1001的訂單數(shù)據(jù)同步到訂單歷史記錄表
- MERGE INTO ORDER_HISTORY H USING
- (
- SELECT ORDER_ID ,--訂單編號
- CUSTOMER_ID ,--客戶編號
- EMPLOYEE_ID ,--員工編號
- ORDER_DATE ,--訂購日期;
- REQUIRED_DATE ,--預(yù)計(jì)到達(dá)日期
- SHIPPED_DATE ,--發(fā)貨日期
- SHIPPER ,--運(yùn)貨商
- FREIGHT ,--運(yùn)費(fèi)
- SHIP_NAM ,--貨主姓名;
- SHIP_ADDRESS ,--貨主地址
- SHIP_CITY ,--貨主所在城市;
- SHIP_REGION ,--貨主所在地區(qū);
- SHIP_POSTALCODE ,--貨主郵編
- SHIP_COUNTRY --貨主所在國家
- FROM ORDER_DTL
- ) O
- ON
- (
- O.ORDER_ID = H.ORDER_ID
- )
- WHEN MATCHED THEN UPDATE SET
- H.CUSTOMER_ID = O.CUSTOMER_ID ,
- H.EMPLOYEE_ID = O.EMPLOYEE_ID ,
- H.ORDER_DATE = O.ORDER_DATE ,
- H.REQUIRED_DATE = O.REQUIRED_DATE ,
- H.SHIPPED_DATE = O.SHIPPED_DATE ,
- H.SHIPPER = O.SHIPPER ,
- H.FREIGHT = O.FREIGHT ,
- H.SHIP_NAM = O.SHIP_NAM ,
- H.SHIP_ADDRESS = O.SHIP_ADDRESS ,
- H.SHIP_CITY = O.SHIP_CITY ,
- H.SHIP_REGION = O.SHIP_REGION ,
- H.SHIP_POSTALCODE = O.SHIP_POSTALCODE ,
- H.SHIP_COUNTRY = O.SHIP_COUNTRY
- WHERE O.EMPLOYEE_ID = '1001'
- WHEN NOT MATCHED THEN INSERT
- (
- H.ORDER_ID ,
- H.CUSTOMER_ID ,
- H.EMPLOYEE_ID ,
- H.ORDER_DATE ,
- H.REQUIRED_DATE ,
- H.SHIPPED_DATE ,
- H.SHIPPER ,
- H.FREIGHT ,
- H.SHIP_NAM ,
- H.SHIP_ADDRESS ,
- H.SHIP_CITY ,
- H.SHIP_REGION ,
- H.SHIP_POSTALCODE ,
- H.SHIP_COUNTRY
- )
- VALUES
- (
- O.ORDER_ID ,
- O.CUSTOMER_ID ,
- O.EMPLOYEE_ID ,
- O.ORDER_DATE ,
- O.REQUIRED_DATE ,
- O.SHIPPED_DATE ,
- O.SHIPPER ,
- O.FREIGHT ,
- O.SHIP_NAM ,
- O.SHIP_ADDRESS ,
- O.SHIP_CITY ,
- O.SHIP_REGION ,
- O.SHIP_POSTALCODE ,
- O.SHIP_COUNTRY
- ) WHERE O.EMPLOYEE_ID = '1001';