1

I have a program on a computer and on a tablet. The program uses SQL Server Express to interact with a local database (the same information on both) from a .MDF file. So if I plug the tablet into the PC, I have two .MDF files that I want to synchronize.

I want both users to be able to make changes to the version on their device, then I want to get both .MDF files and run a script that merges them.

The database has a GUID primary key, and a DateTime of when it was last changed, so if there are conflicts, I would just take the most recent version.

How should I do this?

Or alternatively, if I'm going about this the wrong way, could you recommend an alternative way to keep the databases of these two machines synchronized without an internet connection?

Thanks in advance.

2
  • Usually Merge Replication is the technology used to keep offline databases in synch. Have you tried that? Is express edition used on both computers or just one of them? Commented Apr 14, 2015 at 10:12
  • @spaghettidba I didn't know the right terminology before, but that looks exactly like what I need. From what I've googled, Express can only be a subscriber, not a publisher. Can I still do this with Express? Is the Microsoft Sync Framework an alternative tool I could use? Commented Apr 14, 2015 at 15:32

4 Answers 4

1

Without an internet connection, you would be looking at merge or peer-to-peer replication. Neither of which can be implemented easily (google I seem to remember seeing a workaround somewhere) how you want with Express edition. If you had standard or better edition I would personally go with Peer-To-Peer as it negates the need for an additional column per table and like merge includes conflict resolution. Be advised though that in my opinion replication is a fairly finicky technology and requires intermediate DBA skills to implement and troubleshoot efficiently. Also be advised that once replication is implimented that no transaction can be cleared by a transaction log backup or checkpoint (depending on your recovery model) until it has been distributed to its subscriber. Depending on the duration and number of commands between syncs this will cause your transaction log to grow and potentially fill the disk. Obviously if the avilable disk space becomes full no new transactions can be written / updated in the DB.

With an internet connection I would definitely look at Azure to give you a single database which both devices can write to.

Obviously you can also look to pull and merge the data via powershell, SSIS, C# scripts or get a trial licence of RedGate data compare and kick off via a windows scheduled task (SQL Server agent is not available in express) and do the job which replication would do out of the box.

On a side note depending on your usage you might be able to get hold of developer edition SQL Server licence which is equal to enterprise.

Edit 1: peer to peer is an enterprise only feature in 2008r2 and 2012 at least, unlike merge which is available in standard

5
  • Thanks a ton for your response! Yeah, there would be a ton of advantages to just using everything online and keeping it live but unfortunately that's just not an option in the environment the program needs to run. So if I I get a full version of SQL Server for the publisher, this is possible? Commented Apr 14, 2015 at 17:01
  • Yes, totally possible but like I said replication is not a straight forward technology. Also do yourself a favour and drop the GUID primary key and replace with an INT datatype with IDENTITY(1,1) property. As well as reducing fragmentation and improving performance you will also be better able to determine new records simply based on the identity value. It does however, mean that you will need to manually manage the identity ranges before setting up the replication article per table.
    – Pixelated
    Commented Apr 14, 2015 at 17:09
  • Okay, thanks again. One last question, I'm downloading a trial of RedGate as speak, are there any other third-party tools you recommend I look into? Commented Apr 14, 2015 at 17:13
  • With regards to managing replication no, just become famiar with the replication monitor GUI and look for most replication errors in dbo.msdistribution_history at the distributor database and the job step history of the distribution agents. Go with push subscriptions and if you do go with RedGate data compare you might want to automate via powershell so have a look at the free PowerGUI software for the scripting.
    – Pixelated
    Commented Apr 14, 2015 at 17:17
  • Do not drop the GUID primary key unless you are sure that you will not be using Merge Replication. Commented Apr 14, 2015 at 23:21
0

Since I know Powershell and VB much better than T-SQL, I would use one of those languages to pull new records from each database, loop through them, and insert them into the other database. The script would save a file that contained the timestamp of the last record from each database, which it would use the next time it ran to get the records newer than that date. ...or store the timestamp or the GUID from the last row synced somewhere in the database.

Your terminology of "merging .mdfs" may throw people off here because you aren't going to try to read the files directly and merge the differences. You're just going to query for new records in each database and insert them into the other.

You could approach this by various other methods--this is but one.

0

Take a look at existing technology: replication.

As per the documentation (emphasis added):

Replication is a set of technologies for copying and distributing data and database objects from one database to another and then synchronizing between databases to maintain consistency. Using replication, you can distribute data to different locations and to remote or mobile users.

1
  • Would it be possible for you to provide an example or some sort of guidance on how to do it? I keep getting in these situations where I end up in an infinite loop of microsoft documentation going over my head and linking to other places that links back to where I was... Commented Apr 14, 2015 at 15:02
0

Most existing tools like Microsoft Sync and Merge-Replication ended seeming likebeing way too much overkill and being more hassle than they'd be worth.

This is my SQL Script to attach the databases

CREATE DATABASE LocalDatabase  
ON (Filename = 'C:\ProgramData\Clayton\Database.mdf')
   , (Filename = 'C:\ProgramData\Clayton\Database_log.ldf') 
FOR ATTACH;
GO

EXEC sp_addlinkedserver @server='Server'

Then to sync the databases

-- update the client from the master 
MERGE [LocalDatabase].[dbo].[tableName] trgt
using [Server].[ServerDatabase].[dbo].[tableName] src

ON trgt.id = src.id 

WHEN matched AND trgt.lastmodified <= src.lastmodified THEN 
  -- if the master has a row newer than the client
  -- update the client                       
  UPDATE SET trgt.[allColumns]      = src.[allColumns],
             trgt.[id]              = src.[id], 
             trgt.[lastmodified]    = src.[lastmodified] 

-- delete any rows added by a client 
WHEN NOT matched BY source 
THEN 
  DELETE 

-- insert any rows added by the master 
WHEN NOT matched BY target 
THEN 
  INSERT ( [allColumns], 
           [id], 
           [lastmodified]) 
  VALUES (src. [allColumns], 
          src.[id], 
          src.[lastmodified]); 


-- now we update the master from the client
-- Note:
-- because the serverDB is a linked server 
-- we can't use another MERGE statement, otherwise
-- we get the error: "The target of a MERGE statement 
-- cannot be a remote table, a remote view, or a view over remote tables."

UPDATE
    serverDB

SET 
    [allColumns]        = [localDB].[allColumns],
    [id]                = [localDB].[id], 
    [lastmodified]      = [localDB].[lastmodified] 

FROM 
     [Server].[ServerDatabase].[dbo].[tableName] serverDB

INNER JOIN
     [LocalDatabase].[dbo].[tableName] localDB

-- update where the id is the same but the client is newer than the master

ON serverDB.id = localDB.id 
       AND localDB.lastmodified >= serverDB.lastmodified

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.