The MERGE statement is new in SQL Server 2008. It allows you to synchronize one table with another. This is achieved by performing INSERT, UPDATE, and DELETE operations on a target table based on the results of a join with a source table. Expect to be asked about the MERGE statement in the exam because it is a new feature of SQL Server 2008. The syntax elements shown in Example 7.18 appear most commonly in the MERGE statement.
Example 1. MERGE Statement—Core Elements
MERGE [ TOP (n) [PERCENT] ] [INTO] target_table USING source_table ON merge_search_condition [WHEN MATCHED [AND search_condition] THEN matched_action] [WHEN NOT MATCHED [BY TARGET] [AND search_condition] THEN Not_matched_by_target_action] [WHEN NOT MATCHED BY SOURCE [AND search_condition] THEN Not_matched_by_source_action]
|
The MERGE keyword specifies that a MERGE operation is to be performed. The target_table is the table into which you will be merging the data. The USING source_table clause specifies the table or query from which you will be merging the data. You can also specify a VALUES expression as the source table. You must be able to join this table or
query to the target table. This join between the source and target
tables is how data matches will be established. You can alias both the
source and destination tables using the as
keyword. Although doing this is optional, this practice greatly helps
the readability of your statement. Consider aliasing the target table as
tgt, and the source table or query as src.
The ON merge_search_condition
clause specifies the criteria of the join between the source and target
tables. This join is how SQL Server determines whether the data in the
destination table has been matched by the source table.
The TOP (n) [PERCENT] clause serves the same purpose as it does in the INSERT, UPDATE, and DELETE statements. If this clause is specified, only the top n, or top n percent of rows will be processed by the MERGE operation.
WHEN MATCHED, WHEN NOT MATCHED BY SOURCE, and WHEN NOT MATCHED BY TARGET
specify the actions to be carried out when a match is established, or
when data is found in one table that is not found in another. Valid
actions are UPDATE, INSERT, and DELETE statements.
MERGE Statement Examples
Examples 2 through 4 demonstrate uses of the MERGE
statement. We will start with a simpler example, then work our way
through to more advanced examples. You can run any of these examples
against the AdventureWorks database. Performing the examples yourself
will give you a better understanding of how to use the MERGE statement.
Example 2. Using the MERGE Statement to Insert, Update, and Delete Data
USE AdventureWorks GO
-- Create two tables, Produce and Fruit. Insert values into the tables. CREATE TABLE Produce (Name nvarchar(20), Price smallmoney) GO CREATE TABLE Fruit (Name nvarchar(20), Price smallmoney) GO INSERT Produce VALUES ('Milk', 2.4), ('Honey', 4.99), ('Apples', 3.99), ('Bread', 2.45), ('Pears', 4.00) GO INSERT Fruit VALUES ('Apples', 6.00), ('Pears', 7.00), ('Bananas', 4.95), ('Mandarins', 3.95), ('Oranges', 2.50) GO
-- Show records in both tables. Note that some records (Apples and Pears) are in Produce and in Fruit, but prices differ. There are some records in Produce that are not in Fruit, and some in Fruit that are not in Produce. SELECT * FROM Produce GO SELECT * FROM Fruit GO
-- Use MERGE to update prices in Produce for those records that exist in Fruit. Insert records from Fruit that are not in Produce. Delete any records that are not in Fruit from Produce. MERGE INTO Produce USING Fruit ON (Produce.Name = Fruit.Name) WHEN MATCHED THEN UPDATE SET Price = Fruit.Price
WHEN NOT MATCHED BY TARGET THEN INSERT (Name, Price) VALUES(Fruit.Name, Fruit.Price) WHEN NOT MATCHED BY SOURCE THEN DELETE; GO
-- Show records in Produce. Note that prices for Apples and Pears have been updated; Bananas, Oranges and Mandarins have been inserted; and all non-fruit i.e. Milk, Honey etc. is deleted SELECT * FROM Produce GO
|
Example 3. Using the MERGE Statement with the VALUES Clause
USE AdventureWorks GO
-- Show Data in HumanResources.Department table. Note that the Production Control department is in the Manufacturing group. Note the number of departments. SELECT * FROM HumanResources.Department GO
-- Use MERGE to update prices in Produce for those records that exist in Fruit. Insert records from Fruit that are not in Produce. Delete any records that are not in Fruit from Produce. MERGE INTO HumanResources.Department as Target USING (VALUES('Production Control', 'Inventory Management'), ('Building Security', 'Maintenance Services')) AS Source (DepartmentName, NewGroupName) ON Target.Name = Source.DepartmentName WHEN MATCHED THEN UPDATE SET GroupName = Source.NewGroupName WHEN NOT MATCHED BY TARGET THEN INSERT (Name, GroupName) VALUES(Source.DepartmentName, Source. NewGroupName); GO
-- Show Data in HumanResources.Department again. Note that the Production Control department is now in the Inventory Management group. Note that the Building Security department was added. SELECT * FROM HumanResources.Department GO
|
Example 4. Using the MERGE Statement to Insert and Update Data
USE AdventureWorks GO
-- Use the SELECT...INTO statement to create a new table named ScrapAudit, and insert two values from the Production.ScrapReason table into it SELECT Name INTO dbo.ScrapAudit FROM Production.ScrapReason WHERE Name = 'Wheel misaligned' OR Name = 'Color incorrect' GO
-- Add two new values to the ScrapAudit table INSERT ScrapAudit Values ('Glue not set'), ('Item falling apart') GO
-- Show values in ScrapAudit and Production.ScrapReason. Note that ScrapAudit has two values that are also in the ScrapReason table, and two values that are not. SELECT * FROM ScrapAudit GO SELECT * FROM Production.ScrapReason GO
-- Use the merge statement to insert values that don't exist in Production. ScrapReason from ScrapAudit. Where values exist in both tables, update the ModifiedDate in ScrapReason to be today's date MERGE INTO Production.ScrapReason USING ScrapAudit ON (ScrapReason.Name = ScrapAudit.Name) WHEN MATCHED THEN UPDATE SET ModifiedDate = GETDATE() WHEN NOT MATCHED BY TARGET THEN INSERT (Name, ModifiedDate) VALUES (ScrapAudit.Name, GETDATE()); GO
-- Show values in Production.ScrapReason. Note that the two new values are added, and two existing values show ModifiedDate as today. SELECT * FROM Production.ScrapReason GO
|
Exercise . USING THE MERGE STATEMENT
In this exercise, we will practice using the MERGE statement in various scenarios.
Before you begin, you must have the following software installed on your computer:
This exercise does not depend on you completing any previous exercises.
Open SQL Server Management Studio. Click Start | All Programs | Microsoft SQL Server 2008 | SQL Server Management Studio. Create a new query against the AdventureWorks database. Create
a table named ProductAudit containing the columns ProductID,
ProductName, and ListPrice by executing the following statement. CREATE TABLE ProductAudit (ProductID int PRIMARY KEY, ProductName nvarchar(255), ListPrice money) Insert all products priced over 1,000 from Production.Product into ProductAudit. To do this, execute the following statement: INSERT INTO ProductAudit SELECT ProductID, Product.Name as ProductName, ListPrice FROM Production.Product WHERE ListPrice > 1000 In
the ProductAudit table, reduce the price for all products containing
‘Yellow’ in the name, to 80% of the original. To do this, execute the
following statement: UPDATE ProductAudit SET ListPrice *= 0.8 WHERE ProductName like '%Yellow%' Write and execute a MERGE statement targeting Production. Product performing the following actions: Find all products that exist in both tables, but with different prices. Set the ListPrice for these products to be the value from ProductAudit. Where products are not listed at all in ProductAudit, discontinue them by setting the DiscontinuedDate to today’s date.
Your statement should look like this: MERGE INTO Production.Product USING ProductAudit ON Product.ProductID = ProductAudit.ProductID WHEN MATCHED AND Product.ListPrice <> ProductAudit.ListPrice THEN UPDATE SET ListPrice = ProductAudit.ListPrice WHEN NOT MATCHED BY SOURCE THEN UPDATE SET DiscontinuedDate = GETDATE(); How many rows were updated by this MERGE statement? What would happen if you reran the statement? Write and execute a MERGE statement targeting ProductAudit performing the following actions: Find all products that exist in both ProductAudit and Product, and add 20 to the list price of these products. Find all products that exist in Product, but not in ProductAudit, and add them to the ProductAudit table.
Your statement should look like this: MERGE INTO ProductAudit USING Production.Product ON ProductAudit.ProductID = Product. ProductID WHEN MATCHED THEN UPDATE SET ListPrice += 20.00 WHEN NOT MATCHED BY TARGET THEN INSERT VALUES(Product.ProductID, Product.Name, Product.ListPrice) How many rows were updated by this MERGE statement? What would happen if you reran the statement?
|