Dynamics CRM in the Field

Information from the Microsoft Dynamics CRM PFE team working in the field

Cleaning up CRM Sync Entry tables

Cleaning up CRM Sync Entry tables

Rate This
  • Comments 2

If you’re CRM system has been up and running for a long period of time and your users have the CRM Outlook client installed (or have had it installed in the past) you’ll find many tables starting in SyncEntry_ as well as SubscriptionStatistics_ in your database. These tables are used to track items that are synchronized down to users client machines, however, when users get new client machines or leave the company the tables are left behind indefinitely.  This script has become a cleanup step we run with our customers prior to upgrading or periodically to prune out old sync data.  

Important NOTES about this script:

  • Always make a backup before running this script against your DB. 
  • Running scripts that modify your database are not supported, thus we’ve gone to great lengths to test this and make sure that all entries are cleaned out.  As of today this script can successfully run on:
    • CRM 4.0 UR7 and greater
    • CRM 2011 RTM through CRM 2011 Update Rollup 8
  • Do not modify any parameters or joins in this script or you could risk data damage
  • The script currently deletes all sync data older than 90 days
  • If a users sync entry data were to be deleted, the next time the user attempts to sync their client, the data would be rebuilt automatically
  • To test the script you can edit the “SET @execute = 1” and set it to a “0”, this will allow the script to run in a read-only mode and print out the SQL statements it would run to delete the tables.
Declare 
      @SyncEnt    varchar(60),
      @syncId     uniqueidentifier,
      @SQL        nvarchar(MAX), 
      @execute bit

--To run the deletions set this to 1, if it is 0 it will only print the statements
SET @execute = 1 

DECLARE CRMSync_cursor CURSOR FOR

SELECT Replace(SyncEntryTableName,'SyncEntry_','') as SyncEntryGUID, SubscriptionId from subscription 
where LastSyncStartedOn < GetDate()-90 or LastSyncStartedOn is NULL

OPEN CRMSync_cursor
FETCH NEXT FROM CRMSync_cursor INTO @SyncEnt, @syncId
WHILE @@Fetch_Status = 0
BEGIN
      IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('subscriptionStatistics_'+@SyncEnt) AND type in (N'U'))
      BEGIN
            SET @SQL = 'DROP TABLE SubscriptionStatistics_' +(@SyncEnt)
            IF @execute=1 EXEC sp_executesql @SQL
            IF @execute=0 PRINT @SQL
            IF @execute=1 PRINT 'Dropped table: SubscriptionStatistics_'+(@SyncEnt)+ ' with error: ' + CAST(@@ERROR as varchar(255))
      END
      ELSE
            IF @execute=1 PRINT 'SubscriptionStatistics table does not exist for subscriptionID: ' + CAST(@syncId as varchar(50))
      
      IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('SyncEntry_'+@SyncEnt) AND type in (N'U'))
      BEGIN
            SET @SQL = 'DROP TABLE SyncEntry_' +(@SyncEnt)
            IF @execute=1 EXEC sp_executesql @SQL
            IF @execute=0 PRINT @SQL
            IF @execute=1 PRINT 'Dropped table: SyncEntry_'+(@SyncEnt) + ' with error: ' + CAST(@@ERROR as varchar(255))
      END
      ELSE
            IF @execute=1 PRINT 'SyncEntry table does not exist for subscriptionID: ' + CAST(@syncId as varchar(50))
      
      SET @SQL = 
            'delete from SubscriptionManuallyTrackedObject where subscriptionId = ''' + CAST(@syncId as varchar(50)) + ''';' +
            'delete from subscriptionclients where subscriptionId = ''' + CAST(@syncId as varchar(50)) + ''';' +
            'delete from Subscriptionsyncinfo where subscriptionId = ''' + CAST(@syncId as varchar(50)) + ''';' +
            'delete from subscription where subscriptionId = ''' + CAST(@syncId as varchar(50)) + ''''
      IF @execute=1 EXEC sp_executesql @SQL
      IF @execute=0 PRINT @SQL
      IF @execute=1 PRINT 'Dropped subscription table data for subscriptionId: ' + CAST(@syncId as varchar(50)) + ' with error data: ' + CAST(@@ERROR as varchar(255))
      FETCH NEXT FROM CRMSync_cursor INTO @SyncEnt, @syncId
END
CLOSE CRMSync_cursor
DEALLOCATE CRMSync_cursor

When the script runs you’ll be left with output such as the following showing you what was deleted and if there were any errors:

Dropped table: SubscriptionStatistics_6e64fbf450a1de11932b00155d88bd02 with error: 0
Dropped table: SyncEntry_6e64fbf450a1de11932b00155d88bd02 with error: 0

(0 row(s) affected)

(0 row(s) affected)

(766 row(s) affected)

(1 row(s) affected)
Dropped subscription table data for subscriptionId: 6E64FBF4-50A1-DE11-932B-00155D88BD02 with error data: 0
  • Hi Sean,

    Thanks for posting this script. However, I am wondering i executing this script would break (or not) any guarantee provided by Microsoft on the CRM product?

  • Thanks for the comment @DotNetMatt!  Deleting from DB in many cases will cause concerns for supportability, in the case of sync tables this data is used to track users subscriptions to various data within CRM and is recreated by CRM if deleted - however, you'll only want to truly delete a users subscription if they're not longer using a given subscription (take for instance the user has left the company or they re-installed windows or are using a new PC).  The primary intent for the script is to be run before upgrades or to be run in cases where you have many old subscriptions that need cleanup.  In a worst case scenario situation where deleting a sync table did break a sync - the users subscription will be recreated by the outlook client.  We certainly do not recommend changing the script or applying this same logic to any other tables.  

Page 1 of 1 (2 items)
Leave a Comment
  • Please add 5 and 3 and type the answer here:
  • Post