As John said, I would use a GUID to solve the merge task. And I see two different solutions requiring a GUID:
1) Constantly change the database schema to use the GUID instead of INTEGER (IDENTITY) as the primary key.
This is a good solution in general, but if you have a lot of code other than SQL that has something to do with how your identifiers work, this may require content code changes. Probably, since you are joining databases, you may need to update the application so that it works with data from one region only based on a registered user, etc.
2) Temporarily add a GUID for migration purposes only, and leave the data after the data transfer:
This view is more complex, but as soon as you write this porting script, you can (re) run it several times to rejoin the databases if you screwed it in for the first time. Here is an example:
Table: PERSON (ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL) Table: ADDRESS (ID INT PRIMARY KEY, City VARCHAR(100) NOT NULL, PERSON_ID INT)
Your alternative scripts (note that for all PCs we automatically generate GUIDs):
ALTER TABLE PERSON ADD UID UNIQUEIDENTIFIER NOT NULL DEFAULT (NEWID()) ALTER TABLE ADDRESS ADD UID UNIQUEIDENTIFIER NOT NULL DEFAULT (NEWID()) ALTER TABLE ADDRESS ADD PERSON_UID UNIQUEIDENTIFIER NULL
Then you update FK to match INTEGER:
--// set ADDRESS.PERSON_UID UPDATE ADDRESS SET ADDRESS.PERSON_UID = PERSON.UID FROM ADDRESS INNER JOIN PERSON ON ADDRESS.PERSON_ID = PERSON.ID
You do this for all PCs (automatically generate GUIDs) and FKs (update as shown above).
You are now creating your target database. In this target database, you also add UID columns for all PCs and FKs. Also disable all FK restrictions.
Now you insert from each of the source databases into the target (note: we do not insert PKs and integer FKs):
INSERT INTO TARGET_DB.dbo.PERSON (UID, NAME) SELECT UID, NAME FROM SOURCE_DB1.dbo.PERSON INSERT INTO TARGET_DB.dbo.ADDRESS (UID, CITY, PERSON_UID) SELECT UID, CITY, PERSON_UID FROM SOURCE_DB1.dbo.ADDRESS
After you have inserted the data from all the databases, you run the code opposite to the original to make the integer FKs compatible with the GUID in the target database:
--// set ADDRESS.PERSON_ID UPDATE ADDRESS SET ADDRESS.PERSON_ID = PERSON.ID FROM ADDRESS INNER JOIN PERSON ON ADDRESS.PERSON_UID = PERSON.UID
Now you can delete all UID columns: ALTER TABLE PERSON DROP COLUMN UID ALTER TABLE ADDRESS DROP COLUMN UID ALTER TABLE ADDRESS DROP COLUMN PERSON_UID
So, in the end you should get a fairly long migration script that should do the job for you. The fact is that IT DOABLE
NOTE: everything written here is not verified.