在本教學中將學習如何使用Oracle MERGE
語句來執行更新或基於指定條件插入資料。
Oracle MERGE
語句從一個或多個源表中選擇資料並更新或將其插入到目標表中。 MERGE
語句可指定一個條件來確定是更新資料還是將資料插入到目標表中。
以下說明了Oracle MERGE
語句的語法:
MERGE INTO target_table
USING source_table
ON search_condition
WHEN MATCHED THEN
UPDATE SET col1 = value1, col2 = value2,...
WHERE <update_condition>
[DELETE WHERE <delete_condition>]
WHEN NOT MATCHED THEN
INSERT (col1,col2,...)
values(value1,value2,...)
WHERE <insert_condition>;
下面來仔細看看上面MERGE
語句的語法:
INTO
子句中更新或插入的目標表(target_table
)。USING
子句中的資料源(source_table
)。ON
子句中更新或插入的搜尋條件。對於目標表中的每一行,Oracle都會評估搜尋條件:
true
,則Oracle使用源表(source_table
)中的相應資料更新該行。false
,則Oracle將源表(source_table
)中相應的行插入到目標表(target_table
)中。當想要在單個操作中組合多個INSERT,UPDATE和DELETE語句時,MERGE
語句變得很方便。
因為MERGE
是確定性語句,所以不能在同一個MERGE
語句中多次更新目標表的同一行。
可以將一個可選的DELETE WHERE
子句新增到MATCHED
子句中,以在合併操作之後進行清理。 DELETE
子句只刪除目標表中與ON
和DELETE WHERE
子句匹配的行。
Oracle MERGE前提條件
要執行MERGE
語句,必須在源表上具有INSERT
和UPDATE
物件許可權。 如果使用DELETE
子句,則還必須在目標表上具有DELETE
物件特權。
假設有兩個表:members
和member_staging
。
每當有一個新會員資訊時,則插入一個新的行記錄到members
表。 然後,members
表中的資料將與member_staging
表的資料合併。
以下語句用於建立members
和member_staging
表:
CREATE TABLE members (
member_id NUMBER PRIMARY KEY,
first_name VARCHAR2(50) NOT NULL,
last_name VARCHAR2(50) NOT NULL,
rank VARCHAR2(20)
);
CREATE TABLE member_staging AS
SELECT * FROM members;
使用以下INSERT
語句將範例資料插入到members
和member_staging
表中:
-- insert into members table
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(1,'Abel','Wolf','Gold');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(2,'Clarita','Franco','Platinum');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(3,'Darryl','Giles','Silver');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(4,'Dorthea','Suarez','Silver');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(5,'Katrina','Wheeler','Silver');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(6,'Lilian','Garza','Silver');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(7,'Ossie','Summers','Gold');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(8,'Paige','Mcfarland','Platinum');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(9,'Ronna','Britt','Platinum');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(10,'Tressie','Short','Bronze');
-- insert into member_staging table
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(1,'Abel','Wolf','Silver');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(2,'Clarita','Franco','Platinum');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(3,'Darryl','Giles','Bronze');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(4,'Dorthea','Gate','Gold');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(5,'Katrina','Wheeler','Silver');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(6,'Lilian','Stark','Silver');
將members
表中的資料更新到member_staging
表時,應該執行以下操作:
id
為1
,3
,4
和6
的行記錄,因為表中這些成員的排名或姓氏是不同的。id
為7
到10
的行記錄,這是因為這些行存在於members
表中,但不存在於member_staging
表中。總共有8
行資料需要合併。參考以下圖示 -
以下是一次性執行所有這些操作的MERGE
語句。
MERGE INTO member_staging x
USING (SELECT member_id, first_name, last_name, rank FROM members) y
ON (x.member_id = y.member_id)
WHEN MATCHED THEN
UPDATE SET x.first_name = y.first_name,
x.last_name = y.last_name,
x.rank = y.rank
WHERE x.first_name <> y.first_name OR
x.last_name <> y.last_name OR
x.rank <> y.rank
WHEN NOT MATCHED THEN
INSERT(x.member_id, x.first_name, x.last_name, x.rank)
VALUES(y.member_id, y.first_name, y.last_name, y.rank);
merge
語句根據member_id
列中的值(參見上面的ON
子句),將member
表中的每一行與member_staging
表中的每一行進行比較。
如果兩個表的member_id
列中的值相等,MERGE
語句只有在兩個表的first_name
,last_name
或rank
列的不值時,才將members
表中的first_name
,last_name
或rank
列的不值作為member_staging
對應列的值來更新,否則它將members
的行直接插入member_staging
表。
Oracle按照預期返回了8
行合併資料。
在本教學中,您已學習如何使用Oracle MERGE
語句根據指定的條件更新或插入資料。