程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> SQL Server 2008中的MERGE(不僅僅是合並)

SQL Server 2008中的MERGE(不僅僅是合並)

編輯:關於SqlServer

就像標題呈現的一樣,SQL Server 2008中的MERGE語句能做很多事情,它的功能是根據源表對目標表執行插入、更新或刪除操作。最典型的應用就是進行兩個表的同步。

下面通過一個簡單示例來演示MERGE語句的使用方法,假設數據庫中有兩個表Product及ProductNew,我們的任務是將Product的數據同步到ProductNew(當然同步可能是每天通過Job來自動完成的,在此我們只關注MERGE的使用)。

以下SQL創建示例表:

--源表
CREATE TABLE Product
(
    ProductID    varchar(7) NOT NULL PRIMARY KEY,
    ProductName varchar(100) NOT NULL,
    Price        decimal(13,2) DEFAULT 0
);

INSERT INTO Product
    Values
    ('4100037','優盤',50),
    ('4100038','鼠標',30);

--目標表
CREATE TABLE ProductNew
(
    ProductID    varchar(7) NOT NULL PRIMARY KEY,
    ProductName varchar(100) NOT NULL,
    Price        decimal(13,2) DEFAULT 0
);

下面再來關注MERGE語句的基本語法:

MERGE 目標表

USING 源表

ON 匹配條件

WHEN MATCHED THEN

   語句

WHEN NOT MATCHED THEN

   語句;

以上是MERGE的最最基本的語法,語句執行時根據匹配條件的結果,如果在目標表中找到匹配記錄則執行WHEN MATCHED THEN後面的語句,如果沒有找到匹配記錄則執行WHEN NOT MATCHED THEN後面的語句。注意源表可以是表,也可以是一個子查詢語句。

格外強調一點,MERGE語句最後的分號是不能省略的!

回到我們的示例,顯然Product與ProductNew表的MERGE匹配條件為主鍵ProductID字段,初始情況下,ProductNew表為空,此時肯定執行的是WHEN NOT MATCHED THEN後的語句,我們先只考慮源表遞增的情況,MERGE語句如下:

MERGE ProductNew AS d
USING
    Product
AS s
ON s.ProductID = d.ProductId
    WHEN NOT MATCHED THEN
            INSERT( ProductID,ProductName,Price)
                    VALUES(s.ProductID,s.ProductName,s.Price);

運行後2行受影響,我們已經將Product表的數據同步到了ProductNew表。

現在,我們更新Product表4100037產品的價格,將其修改為55:

UPDATE Product SET Price=55 WHERE ProductID='4100037';

我們也希望每天同步的時候應該將更新後的價格同步到ProductNew表,顯然此時在MERGE語句中應該添加WHEN MATCHED THEN 語句,該語句來更新ProductNew表的價格,添加匹配更新後的MERGE語句:

MERGE ProductNew AS d
USING
    Product
AS s
ON s.ProductID = d.ProductId
WHEN NOT MATCHED THEN
    INSERT( ProductID,ProductName,Price)
        VALUES(s.ProductID,s.ProductName,s.Price)
WHEN MATCHED THEN
    UPDATE SET d.ProductName = s.ProductName, d.Price = s.Price;

執行後2行受影響,為什麼是兩行呢?因為我們的匹配條件只是按ProductID來關聯的,這樣匹配出來的記錄為2行。另外,我們的UPDATE語句裡面沒有更新ProductID字段,因為這是完全沒必要的(如果修改了ProductID字段會直接走到NOT MATCHED)。

現在做個破壞,我們將410037產品刪除掉:

DELETE Product WHERE ProductID='4100037';

明顯,上面給出的MERGE語句無法同步這種情況,再次回到MERGE語句的定義,對MERGE的WHEN NOT MATCHED THEN語句稍作擴展:

WHEN NOT MATCHED BY TARGET

表示目標表不匹配,BY TARGET是默認的,所以上面我們直接使用WHEN NOT MATCHED THEN

WHEN NOT MATCHED BY SOURCE

表示源表不匹配,即目標表中存在,源表中不存在的情況。

現在我們要完成源表DELETE後,目標表的同步動作,MERGE語句如下:

MERGE ProductNew AS d
USING
    Product
AS s
ON s.ProductID = d.ProductId
WHEN NOT MATCHED BY TARGET THEN
    INSERT( ProductID,ProductName,Price)
        VALUES(s.ProductID,s.ProductName,s.Price)
WHEN NOT MATCHED BY SOURCE THEN
    DELETE
WHEN MATCHED THEN
    UPDATE SET d.ProductName = s.ProductName, d.Price = s.Price;

上面已經使用到MERGE語句中的INSERT、UPDATE、DELETE語句,這足夠完成大多數的同步功能了。當然,MERGE語句還有很多的選項,在此不做詳述,請參考MSDN.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved