MSSQL Server 2008中的MERGE(不仅仅是合并)


  就像 题目出现的一样,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.