Answered by:
batching update with SQL Server 2008 change track

Question
-
Hi,
I setup a sync between a windows form application with a sql server 2008 database. I tried to use the batch sp from http://msdn.microsoft.com/en-us/library/bb902828.aspx, but I found it requires to add updatetimestamp and inserttimestamp. In my current enviornment, we are not allowed to change table schema on server side. we can enable change track for specific table. I also change the script based on the one in MSDN, and want to know whether it makes sense.
Table
CREATE TABLE [SyncTest].[OrderTable]( [Id] [uniqueidentifier] NOT NULL, [Name] [nvarchar](50) NOT NULL, [Number] [int] NOT NULL, [UserId] [nvarchar](50) NOT NULL, CONSTRAINT [PK_Order] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
SP
CREATE PROCEDURE usp_GetNewBatchAnchor ( @sync_last_received_anchor bigint, @sync_batch_size bigint, @sync_max_received_anchor bigint out, @sync_new_received_anchor bigint out, @sync_batch_count int output) AS insert into ParameterList (p1,p2,p3,p4,p5) values (@sync_last_received_anchor, @sync_batch_size, @sync_max_received_anchor, @sync_new_received_anchor, @sync_batch_count) -- Set a default batch size if a valid one is not passed in. IF @sync_batch_size IS NULL OR @sync_batch_size <= 0 SET @sync_batch_size = 1000 -- Before selecting the first batch of changes, -- set the maximum anchor value for this synchronization session. -- After the first time that this procedure is called, -- Synchronization Services passes a value for @sync_max_received_anchor -- to the procedure. Batches of changes are synchronized until this -- value is reached. IF @sync_max_received_anchor IS NULL --for tables which don't have timestamp columns. --SELECT @sync_max_received_anchor = MIN_ACTIVE_ROWVERSION() - 1 SELECT @sync_max_received_anchor = CHANGE_TRACKING_CURRENT_VERSION() -- If this is the first synchronization session for a database, -- get the lowest timestamp value from the tables. By default, -- Synchronization Services uses a value of 0 for @sync_last_received_anchor -- on the first synchronization. If you do not set @sync_last_received_anchor, -- this can cause empty batches to be downloaded until the lowest -- timestamp value is reached. IF @sync_last_received_anchor IS NULL OR @sync_last_received_anchor = 0 BEGIN --SELECT @sync_last_received_anchor = MIN(TimestampCol) FROM ( -- SELECT MIN(UpdateTimestamp) AS TimestampCol FROM Sales.Customer -- UNION -- SELECT MIN(InsertTimestamp) AS TimestampCol FROM Sales.Customer -- UNION -- SELECT MIN(UpdateTimestamp) AS TimestampCol FROM Sales.OrderHeader -- UNION -- SELECT MIN(InsertTimestamp) AS TimestampCol FROM Sales.OrderHeader --) MinTimestamp --SELECT @sync_last_received_anchor = MIN(TimestampCol) FROM ( -- SELECT CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('dbo.TestTable')) AS TimestampCol -- MIN(UpdateTimestamp) AS TimestampCol FROM dbo.TestTable -- --UNION -- --SELECT MIN(InsertTimestamp) AS TimestampCol FROM dbo.TestTable --) MinTimestamp select @sync_last_received_anchor = MIN(TimestampCol) from ( select --TABLE_SCHEMA+'.'+TABLE_NAME as name, --object_id(TABLE_SCHEMA+'.'+TABLE_NAME) as id, CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME)) AS TimestampCol from INFORMATION_SCHEMA.TABLES --WHERE TABLE_SCHEMA = 'dbo' ) as timetable SET @sync_new_received_anchor = @sync_last_received_anchor + @sync_batch_size -- Determine how many batches are required during the initial synchronization. IF @sync_batch_count <= 0 SET @sync_batch_count = ((@sync_max_received_anchor / @sync_batch_size) - (@sync_last_received_anchor / @sync_batch_size)) END ELSE BEGIN SET @sync_new_received_anchor = @sync_last_received_anchor + @sync_batch_size -- Determine how many batches are required during subsequent synchronizations. IF @sync_batch_count <= 0 SET @sync_batch_count = ((@sync_max_received_anchor / @sync_batch_size) - (@sync_new_received_anchor / @sync_batch_size)) + 1 END -- Check whether this is the last batch. IF @sync_new_received_anchor >= @sync_max_received_anchor BEGIN SET @sync_new_received_anchor = @sync_max_received_anchor IF @sync_batch_count <= 0 SET @sync_batch_count = 1 END insert into ParameterList (p1,p2,p3,p4,p5) values (@sync_last_received_anchor, @sync_batch_size, @sync_max_received_anchor, @sync_new_received_anchor, @sync_batch_count) GO /* GRANT EXEC ON usp_GetNewBatchAnchor TO PUBLIC GO */
There are couple places I made change.
1: I used CHANGE_TRACKING_CURRENT_VERSION() instead of MIN_ACTIVE_ROWVERSION() because I don't have updatestamp and inserttimestamp in table.
2: I used CHANGE_TRACKING_MIN_VALID_VERSION() function and INFORMATION_SCHEMA.TABLES system view to find out the lowest row from all tables.
another quesiton regarding change track auto clean is that there is a time window in SQL 2008 to clean track change automatically. If we fully rely on change track, we are going to lost some date if client doesn't sync with server with this time window. Anyone knows how to prevant it without change table schema?
Thanks advance
Frank- Moved by Max Wang_1983 Thursday, April 21, 2011 11:30 PM forum consolidation (From:SyncFx - Microsoft Sync Framework Database Providers [ReadOnly])
Wednesday, September 9, 2009 11:03 PM
Answers
-
Changes for Change Tracking looks correct.
Whether Change Tracking information will be cleaned up automatically or not, depends on the configuration of AUTO_CLEARNUP, if it is OFF, you need to clean up manually. Otherwise the time windows is configured by CHANGE_RETENTION:
ALTER DATABASE AdventureWorks SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)
You can also enable change tracking in SQL Server Management Studio by using the Database Properties (ChangeTracking Page) dialog box.
See http://msdn.microsoft.com/en-us/library/bb964713.aspx for more details.- Proposed as answer by Sean_KelleyModerator Sunday, September 13, 2009 10:03 PM
- Marked as answer by Dong CaoMicrosoft employee, Moderator Wednesday, September 23, 2009 6:25 PM
Friday, September 11, 2009 12:43 AM