SQL Server 2008のユーティリティ-merger(回転:http://database.ctocio.com.cn/18/11525518.shtml)

3590 ワード

別のテーブルで見つかった相違に基づいて、1つのテーブルにローを挿入、更新、または削除することで、2つのテーブルを同期できます.
A.MERGEを使用して単一の文の中で表に対してUPDATEとDELETE操作を実行する
次の例では、MERGEを使用して、SalesOrderDetailテーブルで処理された受注に基づいて、AdventureWorksサンプル・データベースのProductInventoryテーブルを毎日更新します.ProductInventoryテーブルのQuantity列は、SalesOrderDetailテーブルの各製品に対する毎日の注文数を減算することによって更新されます.ある製品の受注数によって在庫が0以下に減少した場合、ProductInventoryテーブルから製品に対応するローが削除されます.
B.派生したソーステーブルを利用して、MERGEを使用して目標テーブルに対してUPDATEとINSERT操作を実行する
次の例では、MERGEを使用して、SalesReasonテーブルを更新または挿入して変更します.ソース・テーブルのNewName値がターゲット・テーブル(SalesReason)のName列の値と一致すると、このターゲット・テーブルのReasonType列が更新されます.NewNameの値が一致しない場合、ソース行がターゲットテーブルに挿入されます.このソース・テーブルは、Transact-SQL行構築関数機能を使用してソース・テーブルの複数の行を指定する派生テーブルです.派生テーブルで行構造関数を使用する方法の詳細については、FROM(Transact-SQL)を参照してください.
 
C.MERGE文の実行結果を別の表に挿入する
次の例では、MERGE文のOUTPUT句から返されるデータを取得し、別のテーブルに挿入します.MERGE文は、SalesOrderDetailテーブルで処理された受注に基づいて、ProductInventoryテーブルのQuantity列を更新します.この例では、更新されたローを取得し、在庫の変更を追跡する別のテーブルに挿入します.
USE AdventureWorks; 

GO 

IF OBJECT_ID (N'Production.usp_UpdateInventory', N'P') 

IS NOT NULL DROP PROCEDURE Production.usp_UpdateInventory; 

GO 

CREATE PROCEDURE Production.usp_UpdateInventory 

@OrderDate datetime 

AS 

MERGE Production.ProductInventory AS target 

USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod 

JOIN Sales.SalesOrderHeader AS soh 

ON sod.SalesOrderID = soh.SalesOrderID 

AND soh.OrderDate = @OrderDate 

GROUP BY ProductID) AS source (ProductID, OrderQty) 

ON (target.ProductID = source.ProductID) 

WHEN MATCHED AND target.Quantity - source.OrderQty <= 0 

THEN DELETE 

WHEN MATCHED 

THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty, 

target.ModifiedDate = GETDATE() 

OUTPUT $action, Inserted.ProductID, Inserted.Quantity, Inserted.ModifiedDate, Deleted.ProductID, 

Deleted.Quantity, Deleted.ModifiedDate; 

GO 



EXECUTE Production.usp_UpdateInventory '20030501'


 
 
 
USE AdventureWorks; 

GO 

MERGE INTO Sales.SalesReason AS Target 

USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'), ('Internet', 'Promotion')) 

AS Source (NewName, NewReasonType) 

ON Target.Name = Source.NewName 

WHEN MATCHED THEN 

UPDATE SET ReasonType = Source.NewReasonType 

WHEN NOT MATCHED BY TARGET THEN 

INSERT (Name, ReasonType) VALUES (NewName, NewReasonType) 

OUTPUT $action, inserted.*, deleted.*;

 
 
USE AdventureWorks; 

GO 

CREATE TABLE Production.UpdatedInventory 

(ProductID INT NOT NULL, LocationID int, NewQty int, PreviousQty int, 

CONSTRAINT PK_Inventory PRIMARY KEY CLUSTERED (ProductID, LocationID)); 

GO 

INSERT INTO Production.UpdatedInventory 

SELECT ProductID, LocationID, NewQty, PreviousQty 

FROM 

( MERGE Production.ProductInventory AS pi 

USING (SELECT ProductID, SUM(OrderQty) 

FROM Sales.SalesOrderDetail AS sod 

JOIN Sales.SalesOrderHeader AS soh 

ON sod.SalesOrderID = soh.SalesOrderID 

AND soh.OrderDate BETWEEN '20030701' AND '20030731' 

GROUP BY ProductID) AS src (ProductID, OrderQty) 

ON pi.ProductID = src.ProductID 

WHEN MATCHED AND pi.Quantity - src.OrderQty >= 0 

THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty 

WHEN MATCHED AND pi.Quantity - src.OrderQty <= 0 

THEN DELETE 

OUTPUT $action, Inserted.ProductID, Inserted.LocationID, Inserted.Quantity AS NewQty, Deleted.Quantity AS PreviousQty) 

AS Changes (Action, ProductID, LocationID, NewQty, PreviousQty) WHERE Action = 'UPDATE'; 

GO