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列を更新します.この例では、更新されたローを取得し、在庫の変更を追跡する別のテーブルに挿入します.
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