Monday, November 12, 2007

SQL的新發現--merge

昨天寫程式,突然發現一個很好用的SQL玩意,MERGE在此介紹給大家。
Oracle9i引入了一個新的SQL語句,使用本語句可以在一條語句中連接兩個表。以前要使用UPDATE去更新兩個表中都存在的記錄,或者用INSERT添加兩個合併表中不存在的記錄,必須寫兩個SQL語句,而現在這兩種操作都只要一條SQL MERGE語句就可以實現。例1:
CREATE TABLE inventory (part_nointeger,part_count INTEGER);
INSERT INTO inventory
VALUES (1, 5);
INSERT INTO inventory
VALUES (3, 6);

CREATE TABLE shipment (part_nointeger,part_count INTEGER);
INSERT INTO shipment
VALUES (1, 2);
INSERT INTO shipment
VALUES (2, 2);

MERGE INTO inventory
USING shipment
ON (inventory.part_no = shipment.part_no)
WHEN MATCHED THEN
UPDATE
SET part_count = part_count + shipment.part_count
WHEN NOT MATCHED THEN
INSERT
VALUES (shipment.part_no, shipment.part_count);commit;
SELECT * FROM inventory;

PART_NO PART_COUNT
---------- ----------
1 4
3 6
2 2
執行的結果是shipment資料已經被合併到inventory中,所以與inventory中某些東西相匹配的shipment都會被添加到count中,而沒有得到的匹配的就不會添加到inventory中。
在MERGE語句中必須指定一個WHEN MATCHED和一個WHEN NOT MATHCED語句。如果除這兩種情況之外還有別的情況,你可能就需要使用一個常規的INSERT或者UPDATE語句。
另外一點是MERGE語句一次只能修改一行記錄,而且不能修改在ON子句中引用的列。
MERGE語句的目標表(target table)(在本例中是inventory)必須是一個可以使用INSERT語句進行插入或者UPDATE語句進行更新的表或者視圖。源表(source table)(在例1中是shipment)可以是任何的表格或子查詢,比如說外部表或者管道化表函數。底下是來源表為子查詢的方式:
MERGE INTO c_prs_eqpx eqpx
USING (SELECT 'LOVE123' AS eqp_id
FROM DUAL) eqps
ON (eqpx.eqp_id = eqps.eqp_id)
WHEN MATCHED THEN
UPDATE
SET description = 'test', lm_user = 'royalty', lm_time = SYSDATE
WHEN NOT MATCHED THEN
INSERT (eqp_id, description, lm_user, lm_time)
VALUES ('LOVE123', 'test', 'royalty', SYSDATE)

No comments: