Skip to content

Using Change Tracking

A worked example of polling CHANGETABLE(CHANGES) with an anchor version to pull incremental changes.

Published Feb 4, 2006

The core change tracking pattern. You hold an anchor version - the point in change history you have already consumed - and each poll queries CHANGETABLE(CHANGES table, @AnchorVersion), which returns every row changed since that anchor along with the operation (I/ins, U/upd, D/del) and version numbers. Join back to the base table on the primary key to get current values, filter to versions at or below CHANGE_TRACKING_CURRENT_VERSION() so you only see committed changes, then advance your anchor. The second query shows the same poll twenty minutes later against a different table using the original anchor.

DECLARE @AnchorVersion BigInt
DECLARE @CurrentVersion BigInt

SET @AnchorVersion = 10
SET @CurrentVersion = CHANGE_TRACKING_CURRENT_VERSION()

SELECT @AnchorVersion as AnchorVersion, @CurrentVersion as CurrentVersion

SELECT
	Tracking.SYS_CHANGE_OPERATION,
	Tracking.SYS_CHANGE_VERSION,
	Tracking.SYS_CHANGE_CREATION_VERSION,
	Tracking.<PK Column(s)>,
	Base.*
FROM
    CHANGETABLE(CHANGES dbo.<Table Name>, @AnchorVersion) AS Tracking
LEFT OUTER JOIN dbo.<Table Name> AS Base (NOLOCK)
	ON Base.<PK Column(s)> = Tracking.<PK Column(s)>
WHERE
	Tracking.SYS_CHANGE_VERSION <= @CurrentVersion

--20 minutes passes--

SELECT
	Tracking.SYS_CHANGE_OPERATION,
	Tracking.SYS_CHANGE_VERSION,
	Tracking.SYS_CHANGE_CREATION_VERSION,
	Tracking.<PK Column(s)>,
	Base.*
FROM
    CHANGETABLE(CHANGES dbo.<Some Other Table Name>, @AnchorVersion) AS Tracking
LEFT OUTER JOIN dbo.<Some Other Table Name> AS Base (NOLOCK)
	ON Base.<PK Column(s)> = Tracking.<PK Column(s)>
WHERE
	Tracking.SYS_CHANGE_VERSION <= @CurrentVersion
An unhandled error has occurred. Reload 🗙