Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Links Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS SQL
Oracle
DB2
MS Access
MySQL
» RESOURCES
Database Tools
SQL Scripts & Samples
Links
» Database Forum
» Sitemap
Free Newsletters:
DatabaseDaily  
News Via RSS Feed


follow us on Twitter
Database Journal |DBA Support |SQLCourse |SQLCourse2
 

Featured Database Articles

MS SQL

Posted Mar 5, 2008

Microsoft SQL Server 2008 - Change Data Capture - Part 4

By Muthusamy Anantha Kumar aka The MAK

Change data capture is one of the many features that Microsoft is introducing in SQL Server 2008. Part 1 and Part2 of the article explored how we could enable Change Data Capture on a database and on a table. In Part 3 we discussed how to disable and enable the Change Data Capture when the table structure changes.

This article illustrates how to generate DML [Data Manipulation language – Insert, Update and Delete] statements from the history table.

Note: This article is written based on the SQL Server 2008 – Nov CTP

Step 1

Let’s create the Database “MYDB2” and the table “EMP” under the database “MyDB2” as shown below.

USE [master]
GO
/*** Object:  Database [MyDB2]   Script Date: 02/07/2008 18:46:15 ***/
IF  EXISTS (SELECT name FROM sys.databases WHERE name = N'MyDB2')
DROP DATABASE [MyDB2]
GO
USE [master]
GO
/*** Object:  Database [MyDB1]   Script Date: 02/07/2008 18:46:33 ***/
CREATE DATABASE [MyDB2] 
GO
USE [MyDB2]
go
USE [MyDB2]
GO
/**** Object:  Table [dbo].[Emp]    Script Date: 02/10/2008 10:59:21 ****/
IF  EXISTS (SELECT * FROM sys.objects 
    WHERE object_id = OBJECT_ID(N'[dbo].[Emp]') AND type in (N'U'))
DROP TABLE [dbo].[Emp]
GO
USE [MyDB2]
GO
/**** Object:  Table [dbo].[Emp]    Script Date: 02/10/2008 11:02:58 ****/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Emp](
 [id] [int] NULL,
 [First name] [varchar](50) NULL,
 [Last name] [varchar](50) NULL,
 [gender] [char](1) NULL,
 [Salary] [money] NULL,
 [Bonus] [money] NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO

Step 2

Let’s enable Change Data Capture on the database “MyDB2” and on the table “EMP” as shown below.

USE [MyDB2]
GO
EXEC sys.sp_cdc_enable_db_change_data_capture
GO
use [MyDB2]
go
EXEC sys.sp_cdc_enable_table_change_data_capture 
@source_schema = 'dbo', 
@source_name = 'Emp', 
@role_name = 'cdc_Emp'
GO

Step 3

Now let us insert some real data to the “EMP” table, as shown below.

USE [MyDB2]
GO
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (1,'John', 'Smith','m', 10000, 1000)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (2,'James', 'Bond','m', 20000, 2000)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (3,'Alexa', 'Mantena','f', 22000, 2000)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (4,'Shui', 'Qui','f', 12000, 1200)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (5,'William', 'Hsu','m', 3000, 350)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (6,'Danielle', 'Stewart','F', 45000, 4500)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (7,'Martha', 'Mcgrath','F', 29000, 2000)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (8,'Henry', 'Fayol','m', 4500, 450)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (9,'Dick', 'Watson','m', 20000, 1200)
insert into Emp (id, [First name],[Last name], gender,Salary, Bonus ) 
 values (10,'Helen', 'Foster','F', 34000, 3400)
go

Step 4

Let’s Delete some data from the table “EMP” as shown below.

USE [MyDB2]
GO
Delete from Emp where id in (3,7,10)
Go

Result

home\sql2008(HOME\MAK): (3 row(s) affected)

Step 5

Now update some data from the table “EMP” as shown below.

USE [MyDB2]
GO
Update Emp set Bonus=Salary*.20 where salary >4500
GO

Result

home\sql2008(HOME\MAK): (5 row(s) affected)

Step 6

Let’s query the history table as shown below. [Fig 1.0]

USE [MyDB2]
GO
Select case __$operation when 1 then 'Deleting'
when 2 then 'Inserting'
when 3 then 'Value before Update'
when 4 then 'Value after Update'
when 5 then 'Merge' end as Operation,__$update_mask,id,[First name],[Last name], gender,Salary, Bonus
from cdc.dbo_Emp_CT
go

Result


Fig 1.0

Though the output looks readable, it can’t be used for regenerating the table from the history.

Step 7

Let’s create a small script that generates all of the DML statements for the “EMP” table, as shown below

--Generate DML Statements
set nocount on
declare @tablename varchar(128)
set @tablename='Emp'
select 'Set quoted_identifier off' as [--GenerateDDL]
select 'go' as [--GenerateDDL]
Select case __$operation when 1 then 
'Delete from '+@tablename+ 
' where id='+convert(varchar(20),id)+
' and [First Name]="'+[First Name]+'"'+
' and [Last Name]="'+[Last Name]+'"'+
' and [Gender]="'+[Gender]+'"'+
' and [Salary]='+convert(varchar(20),[Salary])+
' and [Bonus]='+convert(varchar(20),[Bonus])
when 2 then 'Insert into '+@tablename+
'(id, [First name], [Last name], gender, Salary, Bonus ) values ('+
convert(varchar(20),ID)+', "'+
[First Name]+'"'+', "'+
[Last Name]+'"'+', "'+
[Gender]+'"'+', '+
convert(varchar(20),[Salary])+', '+
convert(varchar(20),[Bonus])+')'
when 3 then 
'Delete from '+@tablename+ 
' where id='+convert(varchar(20),id)+
' and [First Name]="'+[First Name]+'"'+
' and [Last Name]="'+[Last Name]+'"'+
' and [Gender]="'+[Gender]+'"'+
' and [Salary]='+convert(varchar(20),[Salary])+
' and [Bonus]='+convert(varchar(20),[Bonus])
when 4 then 'Insert into '+@tablename+
'(id, [First name],[Last name], gender,Salary, Bonus ) values ('+
convert(varchar(20),ID)+', "'+
[First Name]+'"'+', "'+
[Last Name]+'"'+', "'+
[Gender]+'"'+', '+
convert(varchar(20),[Salary])+', '+
convert(varchar(20),[Bonus])+')'
when 5 then 'Merge' end  as [--GenerateDDL]
from cdc.dbo_Emp_CT 
order by __$start_lsn asc

When the above script is executed, it generates the Insert and Delete statement for all of the Insert, Delete and Update actions. Remember, the Update statement is actually a Delete followed by a Insert statement.

Result

--GenerateDDL
Set quoted_identifier off
--GenerateDDL
go
--GenerateDDL
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (1, "John", "Smith", "m", 10000.00, 1000.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (2, "James", "Bond", "m", 20000.00, 2000.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (3, "Alexa", "Mantena", "f", 22000.00, 2000.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (4, "Shui", "Qui", "f", 12000.00, 1200.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (5, "William", "Hsu", "m", 3000.00, 350.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (6, "Danielle", "Stewart", "F", 45000.00, 4500.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (7, "Martha", "Mcgrath", "F", 29000.00, 2000.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (8, "Henry", "Fayol", "m", 4500.00, 450.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (9, "Dick", "Watson", "m", 20000.00, 1200.00)
Insert into Emp(id, [First name], [Last name], gender, Salary, Bonus ) values (10, "Helen", "Foster", "F", 34000.00, 3400.00)
Delete from Emp where id=3 and [First Name]="Alexa" and [Last Name]="Mantena" 
 and [Gender]="f" and [Salary]=22000.00 and [Bonus]=2000.00
Delete from Emp where id=7 and [First Name]="Martha" and [Last Name]="Mcgrath" 
 and [Gender]="F" and [Salary]=29000.00 and [Bonus]=2000.00
Delete from Emp where id=10 and [First Name]="Helen" and [Last Name]="Foster" 
 and [Gender]="F" and [Salary]=34000.00 and [Bonus]=3400.00
Delete from Emp where id=1 and [First Name]="John" and [Last Name]="Smith" and [Gender]="m" and [Salary]=10000.00 and [Bonus]=1000.00
Insert into Emp(id, [First name],[Last name], gender,Salary, Bonus ) values (1, "John", "Smith", "m", 10000.00, 2000.00)
Delete from Emp where id=2 and [First Name]="James" and [Last Name]="Bond" and [Gender]="m" and [Salary]=20000.00 and [Bonus]=2000.00
Insert into Emp(id, [First name],[Last name], gender,Salary, Bonus ) values (2, "James", "Bond", "m", 20000.00, 4000.00)
Delete from Emp where id=4 and [First Name]="Shui" and [Last Name]="Qui" and [Gender]="f" and [Salary]=12000.00 and [Bonus]=1200.00
Insert into Emp(id, [First name],[Last name], gender,Salary, Bonus ) values (4, "Shui", "Qui", "f", 12000.00, 2400.00)
Delete from Emp where id=6 and [First Name]="Danielle" and [Last Name]="Stewart" 
 and [Gender]="F" and [Salary]=45000.00 and [Bonus]=4500.00
Insert into Emp(id, [First name],[Last name], gender,Salary, Bonus ) values (6, "Danielle", "Stewart", "F", 45000.00, 9000.00)
Delete from Emp where id=9 and [First Name]="Dick" and [Last Name]="Watson" and [Gender]="m" and [Salary]=20000.00 and [Bonus]=1200.00
Insert into Emp(id, [First name],[Last name], gender,Salary, Bonus ) values (9, "Dick", "Watson", "m", 20000.00, 4000.00)

Conclusion

Based on the value of the column __$operation we can create scripts that generate DML [Data Manipulation language – Insert, Update and Delete] statements from the history table.

» See All Articles by Columnist MAK



MS SQL Archives

Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 




Latest Forum Threads
MS SQL Forum
Topic By Replies Updated
SQL 2005: SSIS: Error using SQL Server credentials poverty 3 August 17th, 07:43 AM
Need help changing table contents nkawtg 1 August 17th, 03:02 AM
SQL Server Memory confifuration bhosalenarayan 2 August 14th, 05:33 AM
SQL Server Primary Key and a Unique Key katty.jonh 2 July 25th, 10:36 AM


















Thanks for your registration, follow us on our social networks to keep up-to-date