We often need to perform operation that include
1. INSERT Record if it does not exits in Target Table
2. UPDATE or DELETE Record if it already exists in Target Table
There are different ways to perform above operation like using IF, CASE construct etc but none method is better than MERGE statement. In this article, we are going to learn how to use MERGE statement.
Scenario Detail
1. Update Record if Found in Target table
2. Insert Record if Not Found in Target Table
3. Mark Record as Deleted if Deleted at Source
Database Objects and Data used in example
Source Table : HumanResource.Department
CREATE TABLE [HumanResources].[Department]
(
[DepartmentID] [smallint] IDENTITY(1,1) NOT NULL,
[Name] [dbo].[Name] NOT NULL,
[GroupName] [dbo].[Name] NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_Department_DepartmentID] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
)
) ON [PRIMARY]
Target Table : Department_Copy (without IDENTITY property but with Additional column bit type named Deleted)
Key Column Name: Name
Data in Target Table:
Name GroupName ModifiedDate Deleted
Engineering Research and Development 6/1/1998 0
Tool Design Research and Development 6/1/1998 0
Sales Sales and Marketing 6/1/1998 0
Marketing Sales and Marketing 6/1/1998 0
Purchasing Inventory Management 6/1/1998 0
Research and Development Research and Development 6/1/1998 0
Production Manufacturing 6/1/1998 0
Production Control Manufacturing 6/1/1998 0
Human Resources Executive General and Administration 6/1/1998 0
Finance Executive General and Administration 6/1/1998 0
How to use MERGE
Scenario #1
Lets update GroupName for Finance department from "Executive General and Administration" to "Accounts and Finance" using following query:
update HumanResources.Department
set GroupName = 'Accounts and Finance'
where Name = 'Finance'
Now Lets Sync-up Department_Copy table with HumanResources.Department:
MERGE Department_Copy AS deptCopy
USING (SELECT * FROM HumanResources.Department)AS dept
ON (deptCopy.Name = dept.Name)
WHEN MATCHED then
update
set
deptCopy.GroupName = dept.GroupName
,ModifiedDate = getDate()
; -- A MERGE statement must be terminated by a semi-colon (;)
After you execute above statement, you will notice that Department_Copy table has updated value for Department "Finance" with modification date:
Name GroupName ModifiedDate Deleted
Finance Accounts and Finance 4/26/2010 0
Scenario #2
Lets insert new record in HumanResource.Department
insert into HumanResources.Department (Name, GroupName)
values ('Document Control','Quality Assurance')
Now Lets Sync-up Department_Copy table with HumanResources.Department if any new record entered then add in Department_Copy without removing flexibility of changing data if any updated:
MERGE Department_Copy AS deptCopy
USING (SELECT * FROM HumanResources.Department)AS dept
ON (deptCopy.Name = dept.Name)
WHEN MATCHED then
update
set
deptCopy.GroupName = dept.GroupName
,ModifiedDate = getDate()
--following line will add new record if not found in Department_Copy table
WHEN NOT MATCHED BY TARGET THEN
insert
(
DepartmentID
,Name
,GroupName
,ModifiedDate
)
values
(
DepartmentID
,Name
,GroupName
,ModifiedDate
)
;
Scenario #3
Lets delete record in HumanResource.Department but do not delete record in Department_Copy table while synchronizing but need to identity if record was deleted in HumanResoource.Department table
In order to achieve this, I have added an extra column in Department_Copy table named Deleted using bit data type. Now lets examine by performing followings:
delete HumanResources.Department
where Name = 'Finance'
Now, lets synchronize Department_Copy with HumanResource.Department which can flag deleted record along with providing solution for 1st two scenario tested above:
MERGE Department_Copy AS deptCopy
USING (SELECT * FROM HumanResources.Department)AS dept
ON (deptCopy.Name = dept.Name)
WHEN MATCHED then
update
set
deptCopy.GroupName = dept.GroupName
,ModifiedDate = getDate()
--following line will add new record if not found in Department_Copy table
WHEN NOT MATCHED BY TARGET THEN
insert
(
Name
,GroupName
,ModifiedDate
)
values
(
Name
,GroupName
,ModifiedDate
)
--following line will update Deleted column with value 1 if Record(s) is/are deleted in HumanResource.Department table
WHEN NOT MATCHED BY SOURCE THEN
update
set Deleted = 1
;
Result of Scenario # 3 will changed valued for Deleted column for Finance Department as shown below:
Name GroupName ModifiedDate Deleted
Finance Accounts and Finance 4/26/2010 1
Conclusion
MERGE Statement can be used to perform INSERT, UPDATE and DELETE all in single statement
No comments:
Post a Comment