MS Access tables match and synchronize - ms-access

I have 2 computers each having a MS Access database, same set of tables with same structure. I want to match and synchronize both of those databases. I want to create some scheduled task which match all the tables in both databases, check for any new rows or updation of preexisting values, and then update the tables. Is there any way of achieving this within MS Access? if yes, how? or Do I need to write some application in some programming language?
Thanks.

If they're on a LAN then why not share the tables between the two computers? You want to split the MDB into a Front End MDB containing the queries, forms, reports, macros and modules with just the tables and relationships in the Back End MDB. The FE is copied to each network users computer. The FE MDB is linked to the tables in the back end MDB which resides on a server. You make updates to the FE MDB and distribute them to the users, likely as an MDE.
See the "Splitting your app into a front end and back end Tips" page for more info. See the free Auto FE Updater utility to make the distribution of new FEs relatively painless. Although this utility is be overkill for two PCs I mention it for others who will read this posting in the future.

You can create a series of queries to check for changes to tables matched on the key (updates) or missing the key value (additions). The queries can be run through VBA.
EDIT For an external database with a database password:
SELECT *
FROM [MS Access;PWD=password;DATABASE=C:\Docs\LTD.mdb].Companies a
INNER JOIN Companies b
ON a.ID=b.ID
WHERE a.CompanyName<>b.CompanyName
You could also use the above string without the Where statement as a recordset and loop through each field to find mismatches. You can even use VBA and TableDefs to loop through the tables collection and build the SQL strings.
New Record in Companies aliased b
SELECT *
FROM [MS Access;PWD=password;DATABASE=C:\Docs\LTD.mdb].Companies a
LEFT JOIN Companies b
ON a.ID=b.ID
WHERE b.ID Is Null

Related

Query 2 databases on 2 different SQL Servers

In reviewing many of the answers, don't see a solution something I feel should be simple.
I'm attempting to update a couple of fields in my Production database on one server from a restored database on another server because of a loss of data by our ERP vendor's update.
Anyway, have both servers connected in SSMS and just want to run the query below:
USE coll18_production;
GO
USE coll18_test2;
GO
UPDATE coll18_Production.dbo.PERSON
SET W71_ID_CRD_NO = T2.PERSON_USER1, W71_ID_CRD_DATE = T2.PERSON_USER9
FROM coll18_test2.dbo.PERSON as T2
WHERE coll18_Production.dbo.PERSON.ID = T2.ID;
I would think this would be a simple update, but can't make a query for 2 different server databases via the same tables.
Thanks if anyone can make this simple,
Donald
Okay, thanks for the input. In the essence of time I'm going to do something similar to what cpaccho recommended. Create a temp table containing the 2 fields that I want to update from in my Production database. Then I'm going to connect to my Test2 database that I restored from backup. Export these two fields as a csv file with the primary key and simply restore this table data into the temp. table in my production database. Then simply run my update from this temp table into the 2 fields in my production PERSON table where the ID's equal each other.
Have a great weekend,
Donald
The problem is that since the databases are on 2 different servers in order to join between them you will need a way for the servers to talk to each other.
The way to do that is through linked servers. Then you can set up your query to join the 2 tables together using 4 part naming (server.DB.Schema.Table) and accomplish your goal. The query will look sort of like this:
UPDATE Server.DB.Schema.Table1
SET column = b.column
FROM Server1.DB.Schema.Table1 a
INNER JOIN Server2.DB.Schema.Table2 b
ON a.column = b.column
Where a.column = something
You will only need to set up the linked server on one side and the Server name in the query will be the name you give the linked server. The only caveat is that this can be slow because in order to join the tables SQL Server may have to copy the entire table from one server to the other. I would also set up the linked server on the server you are updating (so that you run the update on the same server as the DB you are updating)
How to set up Linked Server Microsoft KB
A simple, rather hacky way would be to hard copy the table from database to database...
First create a table that containts the changes you want:
USE coll18_test2;
GO
SELECT PERSON_USER1, PERSON_USER9, ID
INTO dbo.MyMrigationOrWhateverNameYouLike
FROM coll18_test2.dbo.PERSON
Then go to SSMS, right click on coll18_test2 database --> Task --> Generate scripts and go with the assistant to generate a script for the newly created table. Don't forget to setup, in the advanced options, "Type of data to script" to "Schema and "Data".
Now that you have your script, just run it in your production database, and make your query based on that table.
UPDATE dbo.PERSON
SET W71_ID_CRD_NO = T2.PERSON_USER1, W71_ID_CRD_DATE = T2.PERSON_USER9
FROM dbo.MyMrigationOrWhateverNameYouLike as T2
WHERE coll18_Production.dbo.PERSON.ID = T2.ID;
Finally drop the MyMrigationOrWhateverNameYouLike table and you're done...

Creating new record in form when 3 tables are involved

I have created a form which shows details of users, the data has been split into three tables (table1, table2, table3)
table1 has foriegn keys to link to data in the other tables
The default previous, next and new record selectors worked fine when only table1 was inserted. However after inserting the other two tables the form is unable to create a new record.
I believe its because table2 and table3 are trying to link to the foriegn key in table1.
When pressing "new record" it returns a "You cant go to the specified record."
As one user already pointed out, stored procedures, if available, are definitely the preferred way of making multi-table entries and edits. It's basically a transaction and transactions usually allow you to roll back when an error is encounter.
Access 2010 has stored procedure capabilities built into the database engine but prior versions of Access do not. Other popular database servers such as SQL Server and MySQL also have stored procedure capabilities. To run/call a stored procedure in one of these databases you must either use a Pass Through Query or else use ADO.
Access does have an option on the form level to change your Recordset Type to Dynaset Inconsistent Updates. This allows the form to ignore the relationships in the query that underlies your recordset but any relationships defined in your relationships window will still be honored. You can see a discussion on that here: http://www.utteraccess.com/forum/Dynaset-Inconsistent-Upd-t1664392.html
As pointed out in that discussion, I also design my data entry forms so that they are built on only a single table even if I'm using a query. I then use subforms for data that is in related tables. I think this is pretty much standard design practice in MS Access. Software designed in environments such as .NET can easier violate this because usually the developer is having to write code for all CRUD operations anyway. This gives the developer greater flexibility.
I am not sure what controls you are using, but nevertheless I recomend writing stored procedures for crud operations. This is a good way to update multiple tables

How can I extract sprocs/tables/functions from a specific schema?

I need to extract all the tables, stored procs and functions from an SQL Server 08 db that are under a particular schema. I could filter the displayed items in Management Studio and then do Script As -> Drop/Create for each of them, but I would really like to avoid this as there are quite a few items in the schema.
Is there a way to do this?
Edit:
I've had a look at this question (possible duplicate I just found). I'd rather not use an external tool as suggested, since this is at work and I'd need to get approval to use one. Nor do I want one big Create Database script - I need separate scripts for each table/sproc/function.
select
object_name(obj.object_id),
sch.name,
co.definition
from
sys.objects obj
join sys.schemas sch on sch.schema_id = obj.schema_id
left join sys.sql_modules co on co.object_id = obj.object_id
where
sch.name = 'DBO' --here goes your schema name
--The syscoments table was used back in sql 2000 and you should not use it anymore - but when so it is the sys.syscomments table
Visual Studio 2010 Premium includes database project tooling support that allows you to perform database schema comparisons between databases (where you can filter to only a specified database schema) and extract all the objects (and configuration) in a live database to a VS2010 database project, creating a script per object.
See Working with Database Projects.
Something based on
SELECT [text] FROM [syscomments]

SQL to ACCESS 2010

I imported my SQL information into Access. How can I create a table in Access, then join or link it to an existing table already in Access 2010.
I just use 'Access Data Projects' (ADP). This allows me to keep everything on the SQL Server side, and it allows me to write stored procedures (and bind them to forms, etc) without writing mountains of linked table / SQL passthrough code.
An easy way is to set up a UNION query. That will leave your two tables intact but join the data.
A JOIN query would merge the data into one of the existing tables.
http://stackoverflow.com/questions/38549/difference-between-inner-and-outer-joins post has some good info about that.

Syncronize data between alike tables in mdb file and MySQL server schema

I am looking for a way to manage syncronization between an Access mdb file for an application, and a MySQL schema containing a copy of the same tables. This arose from the fact that the application doesn't support MySQL as a backend, but I am looking for a way to utilize MySQL for other in-office applications using the data the first application generates.
Some givens:
1> We cannot abandon the first application, and it's only compatible with Microsoft SQL Server as a backend server to house data.
2> We are not against using Microsoft SQL server, but the licensing cost is a big concern - as well as rewritting some other Access applications written to use linked tables and seperate mdb files.
3> The database server should be "PHP friendly" for a future expansion project for an internal corporate intraweb.
4> No data needs to be, nor should be allowed to be, accessed from outside the corporate network.
I hope I am not being too obscure, but I don't want to break confidences either - so I am trying to walk a pretty tight rope. If anyone can help, I'd greatly appreciate it.
Synchronizing two databases is very, very complicated if both databases need to be updatable. If one is a slave of the other, it's not nearly as difficult. I have more than once programmed just this kind of synchronization using Access, once with an MDB on a web server that had to be synched with a local data MDB (to incorporate data edited on the website; no edits went back to the website, so one-way synch, but still the need to merge edits on the non-web side), as well as once programming a synch between MySQL on a website and Access in a master (MySQL) / slave (Access) relationship.
On the website, you program a dump of data for each table to a text file. It's helpful to have timestamp fields in the MySQL tables so that you know when records were created and updated. This allows you to select which records to dump since the last data dump (which makes the synchronization of data on the Access side much simpler).
The way I programmed it was to then import the text files into staging tables that were indexed appropriately and linked to the front-end Access app. Once the data dumps are imported into the staging tables, you then have three tasks:
find the new records and append them to the Access data store. This is easily done with an outer join.
deal with the deletions. I'll discuss this later, as it's, well, complicated.
deal with updated records. For this, I wrote DAO code that would write column-by-column SQL statements.
Something like this:
UPDATE LocalTable
SET LocalTable.Field1 = DownloadTable.Field2, LocalTable.Updated = DownloadTable.Updated
WHERE LocalTable.Field1 <> DownloadTable.Field2
Now, obviously, the WHERE clause has to be a bit more complicated than that (you have to deal with NULLs, and you have to use criteria formatted appropriately for the data types, i.e., with "" and ## for text and dates, respectively, and no delimiters for numeric data), but writing the code to do that is pretty easy.
Skeleton code looks something like this:
Dim db As DAO.Database
Dim rsFields As DAO.Recordset
Dim fld As DAO.Field
Dim strSQL As String
Set rsFields = db.OpenRecordset("SELECT TOP 1 Field1, Field2, Field3 FROM LocalTable;")
For Each fld in rsFields
[write your SQL statement and execute it]
Next fld
Set fld = Nothing
rsFields.Close
Set rsFields = Nothing
Set db = Nothing
Now, as I said, the complicated part is writing the WHERE clause for each SQL statement, but that's pretty easy to figure out. Also, note that in your rsFields recordset (which is used only to walk through the fields you want to update) you want to include only the fields that are updatable, so you'd leave out the CREATED field and the PK field (and any other fields that you don't want to update).
Now, for the DELETES.
You might think it's a good idea to simply delete any record in the local table that's not in the remote table. That works fine if it really is a slave database, but so often what is originally a slave ends up getting its own edits. So, in that case, you need to not delete records from the master MySQL database, and instead have a DELETE flag that marks records deleted. You could have different varieties of logic that could clean the deleted records out of the master database (e.g., if you're using date stamps in the records, you could delete all records flagged DELETED with LastUpdated timestamp that is <= the last time you dumped the data; alternatively, you could have the Access app send a text file up to the server with a list of the records that have been successfully deleted from the Access data store). If there are edits in the Access data store, then you'll need some logic for dealing with an edit there on a record that was deleted from the MySQL "master" database.
In summary:
If you have a true master/slave relationship, it's fairly trivial. If you really wanted to do it by brute force, you'd just dump the entirety of all the MySQL data tables to text files, delete all the records in your Access data store and import the text files.
I would tend not to do that, as the first time you need to depart from the pure master/slave relationship, you're hosed and have to rewrite everything from scratch.
The outline I gave above will work very cleanly for master/slave, but will also work well if you have a few fields that are private to the "slave" database, or data that exists in the slave and not in the master (which is the situation I was working with).