How to Enable Change Tracking in a SQL Server Database Project

Problem

I use the SQL Server Database Project for developing, maintaining, and publishing/deploying my databases.  I need to implement Change Tracking in one of my databases.  How can I do that in the SQL Server Database Project?

Solution

The SQL Server Database Project can be used to manage the development and deployment of a SQL Server database.  You can download the SQL Server Data Tools for Visual Studio 2012 here

The SQL Server Database Project has a “publishing” capability which essentially allows you to generate a T-SQL script to deploy your database to a target server.  As part of the publishing capability, you can use a Post-Deployment script which is T-SQL code that gets included in the script that is generated when you publish your database.  The T-SQL code in the Post-Deployment script gets executed after the database objects have been created; e.g. tables, views, stored procedures, etc.  A key point to note about the Post-Deployment script is that it is executed every time you publish your database, even if you are only publishing updates rather than the full database. 

In this tip I will start off with how to setup change tracking with just T-SQL code, then perform the following in a SQL Server database project:

  • Enable change tracking for the database
  • Enable change tracking for a table in the Post-Deployment script
  • Setup a publishing profile
  • Generate a T-SQL script to publish the database

I am going to assume that you are familiar with the SQL Server database project.  If you haven’t used it before or need a refresher, take a look at the Creating a New Database Project Tutorial.  Although it’s based on the 2010 version, it will get you up-to-speed quickly.

Setup SQL Server Change Tracking with T-SQL

Change Tracking is a feature that when enabled will keep track of the rows that are inserted, updated or deleted in a table.  Change Tracking needs to be enabled at the database level and also enabled on each table that you want to track.  If you would like more details on Change tracking, take a look at the tip Using Change Tracking in SQL Server 2008

Assuming we have a database named MSSQLTIPS_CT_DEMO, run the following T-SQL code to enable change tracking on the database (retain change tracking data for 5 days and automatically clean it up):

 ALTER DATABASE MSSQLTIPS_CT_DEMO
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 5 DAYS, AUTO_CLEANUP = ON);
GO

To see the list of databases that have change tracking enabled, run the following T-SQL code:

SELECT DB_NAME(database_id) [DATABASE_NAME] 
FROM sys.change_tracking_databases;
GO

Assuming we have a table named CUSTOMER, run the following T-SQL code to enable change tracking on the CUSTOMER table (just track the rows that have changed without the column change detail):

ALTER TABLE dbo.CUSTOMER
ENABLE CHANGE_TRACKING
WITH (TRACK_COLUMNS_UPDATED = OFF);
GO

To see the list of tables that have change tracking enabled, run the following T-SQL command:

SELECT OBJECT_NAME(object_id) [TABLE_NAME]
FROM sys.change_tracking_tables;
GO

Perform an insert to generate some change tracking data:

INSERT dbo.CUSTOMER ([NAME]) VALUES ('ABC COMPANY');
GO

Query the change tracking data by running the following T-SQL code:

SELECT ct.ID, ct.SYS_CHANGE_OPERATION, c.[NAME]
FROM CHANGETABLE(CHANGES dbo.CUSTOMER, 0) ct
JOIN dbo.CUSTOMER c ON c.[ID] = ct.[ID];
GO

Sample SQL Server Database Project

In lieu of going through the steps to create a SQL Server database project, I’m providing the following screen shot of the completed database project in the SQL Server Data Tools Solution Explorer:

Solution Explorer

Enable Change Tracking for the SQL Server Database

To setup change tracking for the database, we will need to set some properties for the project.  Right-click on the database project in the Solution Explorer and select Properties; you will see the Project Settings:

Project Settings

Click the Database Settings button, select the Operational tab, and fill in the Change Tracking properties as shown below:

Change Tracking properties

Enable SQL Server Change Tracking for a Table

We need to create a Post-Deployment script in our SQL Server database project that will use T-SQL code to enable change tracking on specific tables when we publish to a target server. 

Perform the following steps to add the Post-Deployment script:

  1. Add a Scripts folder to the project: Right-click the project (change-tracking-database-project-sample) in the Solution Explorer, select Add, New Folder; name the folder Scripts
  2. Add a Post-Deployment script to the project: Right-click the Scripts folder in the Solution Explorer, select Add, Post-Deployment script; accept the default file name
  3. Add the following T-SQL code to the Post-Deployment script:
IF NOT EXISTS (SELECT 1 FROM sys.change_tracking_databases 
               WHERE database_id = DB_ID())
BEGIN
     ALTER DATABASE [$(DatabaseName)]
     SET CHANGE_TRACKING = ON
     (CHANGE_RETENTION = 5 DAYS, AUTO_CLEANUP = ON);
END
               
IF NOT EXISTS (SELECT 1 FROM sys.change_tracking_tables 
               WHERE object_id = OBJECT_ID('dbo.CUSTOMER'))
BEGIN
     ALTER TABLE dbo.CUSTOMER
     ENABLE CHANGE_TRACKING
     WITH (TRACK_COLUMNS_UPDATED = OFF)
END

Main points about the above code:

Note that you can only have one Post-Deployment script in the SQL Server database project.

Add a Publishing Profile

A publishing profile is saved with the project and stores various settings for the publishing operation.  The idea is that you can create a different publishing profile for each of your target environments; e.g. development, testing, production, etc.

 Follow these steps to add a publishing profile:

  1. Right click the project in the Solution Explorer and select Publish
  2. Fill in the dialog as shown below:
Publish Profile

Main points about the above dialog:

One thing that I like to do when I’m developing a database is to specify that every time I publish, a new database is created.  This keeps my database clean and the contents of the database always match the project exactly.  To automatically create a new database each time you publish, click the Advanced button on the Publish Database dialog and check Always re-create database as shown below:

Advanced Publish Settings

The way that I use publishing is I have separate profiles for development, QA, production, etc.  Usually I would only specify Always re-create database in a publishing profile for development.

After you have saved one or more publishing profiles in the database project, you can simply double click it in the Solution Explorer to open it up and publish the database or generate a T-SQL script that you will run at a later time.

Publish the Database

Double click on the saved publishing profile in the Solution Explorer to bring up the Publish Database profile and click the Publish button.  The Data Tools Operations window will show messages as the publishing operation proceeds.  If there are any errors, click View Results to investigate.

In lieu of publishing immediately, you can click the Generate Script button which will generate T-SQL code that you can run in SQL Server Management Studio (SSMS) or with the SQLCMD utility. The code requires that you enable SQLCMD mode; in SSMS you can do this by clicking Tools, Options, Query Execution, SQL Server, General and checking By default, open new queries in SQLCMD mode.  This will take effect with the next query window that you open in SSMS.

One thing I noticed about the publish operation is that if you do not specify Always re-create database, the following code will be included in the T-SQL script:

IF EXISTS (SELECT 1
           FROM   [master].[dbo].[sysdatabases]
           WHERE  [name] = N'$(DatabaseName)')
    BEGIN
        ALTER DATABASE [$(DatabaseName)]
            SET CHANGE_TRACKING = OFF 
            WITH ROLLBACK IMMEDIATE;
    END

GO
USE [$(DatabaseName)];

GO
PRINT N'Altering [dbo].[CUSTOMER]...';

GO
ALTER TABLE [dbo].[CUSTOMER] DISABLE CHANGE_TRACKING;
  WITH (TRACK_COLUMNS_UPDATED = OFF)

Essentially if the database exists, the script will turn off change tracking at the database level. However, if the database exists and any tables are enabled for change tracking, the ALTER DATABASE SET CHANGE TRACKING OFF statement will raise an error.

You will probably need to manually edit the T-SQL script and remove the ALTER DATABASE SET CHANGE TRACKING OFF and any ALTER TABLE commands that turn off change tracking for the table.

Next Steps

Leave a Reply

Your email address will not be published. Required fields are marked *