views:

75

answers:

4

We have a program in which each user is given their own Access database. We'd like to merge these all together into a single SQL Server database.

The problem is that, using the SQL Server import/export wizard, the primary/foreign keys do not get updated. So for instance if one user has this table:

1  Apple
2  Banana

and another user has this:

1  Coconut
2  Cheeseburger

the resulting table looks like this:

1  Apple
2  Banana
1  Coconut
2  Cheeseburger

Similarly, anything that referenced Banana by its primary key (2) is now referencing both Banana and Cheeseburger, which will not make the vegans very happy.

Is there any way to automatically update the primary/foreign key references when importing, other than writing an extremely long and complex import-script?

A: 

If you need to keep them fully compartmentalized, you have to assign some kind of partitioning column to each table. Is there a reason you need your SQL Server to have the same referential integrity as Access? Are you just importing to SQL Server for read-only reporting? In that case, I would not bother with RI. The queries will all require a partitionid/siteid/customerid. You could enforce that for single-entity access by wrapping tables with a table-valued UDF which required the partitionid. For cross-site that doesn't work.

If you are just loading to SQL Server for reporting, I would also consider altering the data model to support reporting (i.e. a dimensional model is sometimes better than a normalized model) instead of worrying about transaction processing.

I think we need to know more about the underlying goals.

Cade Roux
Yes, it's a full application - there's got to be a better way than having to modify every table, every query, and writing a custom script to load in every database though. Hasn't anyone ever had to merge two databases before!?
BlueRaja - Danny Pflughoeft
@BlueRaja - Yes, it's decidedly non-trivial - that's why typically multi-tenant architecture is part of the original requirements. Code generation can certainly help - I don't do much of anything manually in the database - probably about 60% of my code is generated with about 30% generated and tweaked. Without triggers and generated views, the manual portion of actual code would go way up, but you get the idea.
Cade Roux
A: 

Why not let Access use its replication manager to merge the databases? This will allow you to identify the conflicts and resolve them before importing to SQL Server. I'm fairly confident it will retain the foreign key relationships. If I understand your situation correctly, and the databases are the same structure with different data, you could load the combined database to the application and verify the data before moving to SQL Server.

What version of Access are you using? Here's a link for Access 2000. Use the language to adjust search parameters to fit your version.

http://technet.microsoft.com/en-us/library/cc751054.aspx

Arthur Miller
Here's a link with some FAQ's regarding Access Replication Manager: http://support.microsoft.com/kb/282977
Arthur Miller
Please explain how you can use Jet Replication to merge the data in two non-replicated Jet databases.
David-W-Fenton
A: 

Need more information of requirements.

My basic question is 'Do you need to preserve the original record key?' e.g. 1:apple in table T of user-database A; 1:coconut in table T of user-database B. Table T is assumed to have the same structure in all database instances. Reasons I can suppose that you may want to preserve the original data: (a) you may have a requirement to the reference the original data (maybe a visual for previous reporting), and/or (b) there may be a data dependency in the application itself.

If the answer is 'no,' then you are probably interested only in preserving all of the distinct data values. Allow the SQL table to build using a new key and constrain the SQL table field such that it contains unique data. This approach seems to preserve the original table structure (but not the original key value or its 'location') and may suffice to meet your requirement.

If the answer is 'yes,' I do not see a way around creating an index that preserves a pointer to the original database and the key that was created in its table T. This approach would seem to require an application modification.

The best approach in this case is probably to split the incoming data into two tables: one to identify the database and original key, another to identify the distinct data values. For example: (database) table D has records such as 'A:1:a,' 'A:2:b,' 'B:1:c,' 'B:2:d,' 'B:15:a,' 'C:8:a'; (data) table T1 has records such as 'a:apple,' 'b:banana,' 'c:coconut,' 'd:cheeseburger' where 'A' describes the original database 'location,' 1 is the original value in location 'A,' and 'a' is a value that equates records in table D and table T1. (Otherwise you have a lot of redundant data in the one table; e.g. A:1:apple, B:15:apple, C:8:apple.) Also, T1 has a structure similar to the original T and is seems to be more directly useful in the application.

TonBill
A: 

Ended up creating an SSIS project for this. SSIS is a visual programming tool made by Microsoft (and part of their "Business Integration Studio", which comes with SQL Server) designed for solving exactly these sorts of problems.

BlueRaja - Danny Pflughoeft