I have 2 MSSQL databases in 2 servers and I need to replicate amendments in schema and in particular tables. Most preferably I need SQL commands to do so. The system should be able to take a snapsnot of initial state of the database and later generate an SQL that would display the changes.
I need to record only particular tables changes in data and I also need to detect changes in table format (alterations of schema). It is desirable that manual adjustment of replication SQL would be possible (so only necessary changes are reflected, in case automated rules allow some unnecessary queries to end up in the patch.
Thanks !
Have a look at RedGate SQL Developer bundle. Unfortunately I'm not aware of any good open source tool for MS SQL Server.
I think that especially SQL Compare could be helpfull for you. If you are using Visual Studio Team Edition, you can have a look at the VS Database projects. I've heard that some teams are successfully using it for their database change management, but I never tried it myself.
I have a vb.net project that uses a SQLite database. I do this by using dataset/table adapters. The client is happy and all works well. However I have just heard that they plan on providing this product to another customer that wishes to use their SQL Server database. So I am writing this post so I can mentally prepare for this before I begin. I am not a database pro and have really enjoyed the simplicity of setting up and managing an SQLite database.
So any ideas on the easiest way to support SQL Server as well? I am happy to run them parallel to each other. Can I just make a separate service / middleware that syncs the SQLite database to the SQL Server on a timer and does not care about what the main app is up to?
Any pointers are appreciated.
Synchronizing two databases is possible, if rather complex. You need some mechanism to find out which records have changed, and if it is possible to have new changes in both databases, you also have to resolve conflicts.
A timer-based approach doesn't sound efficient: in most cases, the timer doesn't have anything to do; and after some data change, there is some amount time where the databases are not synchronized.
Can't you just replace SQLite with MS SQL Server?
I.e., have some configuration settings that determines whether your program's data lies in SQLite or on a server?
Assuming that an SQL Server database with the required structure already exist, this would, in theory, need nothing more than a changed connection string, and supplying some user name/password (if the server isn't configured to automatically use Windows logins).
There shouldn't be any big differences in the SQL dialects used. You have, of course, to test all your queries.
Bear in mind here, I am not an Access guru. I am proficient with SQL Server and .Net framework. Here is my situation:
A very large MS Access 2007 application was built for my company by a contractor.
The application has been split into two tiers BY ACCESS; there is a front end portion that holds all of the Ms Access forms, and then on the back end part, which are access tables, queries, etc., that is stored on a computer on the network.
Well, of course, there is a need to convert the data storage portion to SQL Server 2005 while keeping all of these GUI forms which were built in Ms Access. This is where I come in.
I have read a little, and have found that you can link the forms or maybe even the access tables to SQL Server tables, but I am still very unsure on what exactly can be done and how to do it.
Has anyone done this? Please comment on any capabilities, limitations, considerations about such an undertaking. Thanks!
Do not use the upsizing wizard from Access:
First, it won't work with SQL Server 2008.
Second, there is a much better tool for the job:
SSMA, the SQL Server Migration Assistant for Access which is provided for free by Microsoft.
It will do a lot for you:
move your data from Access to SQL Server
automatically link the tables back into Access
give you lots of information about potential issues due to differences in the two databases
keeps track of the changes so you can keep the two synchronised over time until your migration is complete.
I wrote a blog entry about it recently.
You have a couple of options, the upsizing wizard does a decent(ish) job of moving structure and data from access to Sql. You can then setup linked tables so your application 'should' work pretty much as it does now. Unfortunately the Sql dialect used by Access is different from Sql Server, so if there are any 'raw sql' statements in the code they may need to be changed.
As you've linked to tables though all the other features of Access, the QBE, forms and so on should work as expected. That's the simplest and probably best approach.
Another way of approaching the issue would be to migrate the data as above, and then rather than using linked tables, make use of ADO from within access. That approach is kind of famaliar if you're used to other languages/dev environments, but it's the wrong approach. Access comes with loads of built in stuff that makes working with data really easy, if you go back to use ADO/Sql you then lose many of those benefits.
I suggest start on a small part of the application - non essential data, and migrate a few tables and see how it goes. Of course you back everything up first.
Good luck
Others have suggested upsizing the Jet back end to SQL Server and linking via ODBC. In an ideal world, the app will work beautifully without needing to change anything.
In the real world, you'll find that some of your front-end objects that were engineered to be efficient and fast with a Jet back end don't actually work very well with a server database. Sometimes Jet guesses wrong and sends something really inefficient to the server. This is particular the case with mass updates of records -- in order not to hog server resources (a good thing), Jet will send a single UPDATE statement for each record (which is a bad thing for your app, since it's much, much slower than a single UPDATE statement).
What you have to do is evaluate everything in your app after you've upsized it and where there are performance problems, move some of the logic to the server. This means you may create a few server-side views, or you may use passthrough queries (to hand off the whole SQL statement to SQL Server and not letting Jet worry about it), or you may need to create stored procedures on the server (especially for update operations).
But in general, it's actually quite safe to assume that most of it will work fine without change. It likely won't be as fast as the old Access/Jet app, but that's where you can use SQL Profiler to figure out what the holdup is and re-architect things to be more efficient with the SQL Server back end.
If the Access app was already efficiently designed (e.g., forms are never bound to full tables, but instead to recordsources with restrictive WHERE clauses returning only 1 or a few records), then it will likely work pretty well. On the other hand, if it uses a lot of the bad practices seen in the Access sample databases and templates, you could run into huge problems.
It's my opinion that every Access/Jet app should be designed from the beginning with the idea that someday it will be upsized to use a server back end. This means that the Access/Jet app will actually be quite efficient and speedy, but also that when you do upsize, it will cause a minimum of pain.
This is your lowest-cost option. You're going to want to set up an ODBC connection for your Access clients pointing to your SQL Server. You can then use the (I think) "Import" option to "link" a table to the SQL Server via the ODBC source. Migrate your data from the Access tables to SQL Server, and you have your data on SQL Server in a form you can manage and back up. Important, queries can then be written on SQL Server as views and presented to the Access db as linked tables as well.
Linked Access tables work fine but I've only used them with ODBC and other databases (Firebird, MySQL, Sqlite3). Information on primary or foreign keys wasn't passing through. There were also problems with datatype interpretation: a date in MySQL is not the same thing as in Access VBA. I guess these problems aren't nearly as bad when using SQL Server.
Important Point: If you link the tables in Access to SQL Server, then EVERY table must have a Primary Key defined (Contractor? Access? Experience says that probably some tables don't have PKs). If a PK is not defined, then the Access forms will not be able to update and insert rows, rendering the tables effectively read-only.
Take a look at this Access to SQL Server migration tool. It might be one of the few, if not the ONLY, true peer-to-peer or server-to-server migration tools running as a pure Web Application. It uses mostly ASP 3.0, XML, the File System Object, the Data Dictionary Object, ADO, ADO Extensions (ADOX), the Dictionary Scripting Objects and a few other neat Microsoft techniques and technologies. If you have the Source Access Table on one server and the destination SQL Server on another server or even the same server and you want to run this as a Web Internet solution this is the product for you. This example discusses the VPASP Shopping Cart, but it will work for ANY version of Access and for ANY version of SQL Server from SQL 2000 to SQL 2008.
I am finishing up development for a generic Database Upgrade Conversion process involving the automated conversion of Access Table, View and Index Structures in a VPASP Shopping or any other Access System to their SQL Server 2005/2008 equivalents. It runs right from your server without the need for any outside assistance from external staff or consultants.
After creating a clone of your Access tables, indexes and views in SQL Server this data migration routine will selectively migrate all the data from your Access tables into your new SQL Server 2005/2008 tables without having to give out either your actual Access Database or the Table Contents or your passwords to anyone.
Here is the Reverse Engineering part of the process running against a system with almost 200 tables and almost 300 indexes and Views which is being done as a system acceptance test. Still a work in progress, but the core pieces are in place.
http://www.21stcenturyecommerce.com/SQLDDL/ViewDBTables.asp
I do the automated reverse engineering of the Access Table DDLs (Data Definition Language) and convert them into SQL equivalent DDL Statements, because table structures and even extra tables might be slightly different for every VPASP customer and for every version of VP-ASP out there.
I am finishing the actual data conversion routine which would migrate the data from Access to SQL Server after these new SQL Tables have been created including any views or indexes. It is written entirely in ASP, with VB Scripting, the File System Object (FSO), the Dictionary Object, XML, DHTML, JavaScript right now and runs pretty quickly as you will see against a SQL Server 2008 Database just for the sake of an example.
It takes perhaps 15-20 seconds to reverse engineer almost 500 different database objects. There might be a total of over 2,000 columns involved in this example for the 170 tables and 270 indexes involved.
I have even come up with a way for you to run both VPASP systems in parallel using 2 different database connection files on the same server just to be sure that orders entered on the Access System and the SQL Server system produce the same results before actual cutover to production.
John (a/k/a The SQL Dude)
sales#designersyles.biz
(This is a VP-ASP Demo Site)
Here is a technique I've heard one developer speak on. This is if you really want something like a Client-Server application.
Create .mdb/.mde frontend files distributed to each user (You'll see why).
For every table they need to perform an CRUD, have a local copy in the file in #1.
The forms stay linked to the local tables.
Write VBA code to handle the CRUD from the local tables to the SQL Server database.
Reports can be based off of temp tables created from the SQL Server (Won't be able to create temp tables in mde file I don't think).
Once you decide how you want to do this with a single form, it is not too difficult to apply the same technique to the rest. The nice thing about working with the form on a local table is you can keep a lot of the existing functionality as the existing application (Which is why they used and continue to use Access I hope). You just need to address getting data back and forth to the SQL Server.
You can continue to have linked tables, and then gradually phase them out with this technique as time and performance needs dictate.
Since each user has their own local file, they can work on their local copy of the data. Only the minimum required to do their task should ever be copied locally. Example: if they are updating a single record, the table would only have that record. When a user adds a new record, you would notice that the ID field for the record is Null, so an insert statement is needed.
I guess the local table acts like a dataset in .NET? I'm sure in some way this is an imperfect analogy.
We have several SQL Server 2000 databases (I know, we need to upgrade) that have the same structure and have them set up to replicate to another server. The problem is that whenever I have to change the structure (which is usually pretty easy to do on all databases, especially with tools from Red Gate) I have to stop the replication, make the structure changes, and then set up replication again. The steps to set up replication only take a few minutes to do for each database but it's repetitive and drives me crazy. I have the IDE create a script of the replication procedure and then just replace the name of the prior database with the name of the next database and run the script. Still annoying but faster than clicking though the IDE and forgetting an option.
I've tried things like using the "SP_MSFOREEACHDB" but that didn't look very promising.
My guess is I should just use the TSQL that gets generated from the IDE and use that as a starting point to build a new TSQL script have it pass the name of the database as a parameter. And then when something changes with the structure of the database I need to address that in the TSQL replication script and make the changes there. Is this an issue for anyone else? Does 2005 or 2008 have a better "SP_MSFOREACHDB" so I wouldn't have to mainting some crazy script and just have the IDE generate a script when there are changes that I could then use on multiple databases easily?
Are you using SQL Server replication? If so, why aren't you making the changes to the publishing database and letting it push out the schema changes to its subscribers? We do this occasionally on SQL 2005 and it works well for the most part; I don't have any experience with replication on 2000 servers.
If you can use SQL Server Management studio, then the SSMS tools pack has a widget to allow the same script to be run on different databases.
SQLCMD tool can connect to SQL Server 2000 and enable interaction from command line. Using parametrized queries and a fixed set of .bat files (one for each server) can be a good alternative for what you do now.
I'm using two SQL Server, one is SQL Server 2000 and the other one is SQL Server 2005.
When the table1 in SQL Server 2000 gets updated/inserted/deleted, I have to update another table in SQL Server 2005. Is it possible to achieve that in a trigger? If not, what would be the possible options?
Thank you, have a nice day!
If you're wanting to replicate the data, not just set something differently, you should look at SQL Replication as it'll manage things a lot better. eg it will do the updates asynchronously.
If you have to do them synchronously, or you just decide it's simpler or you need the whole operation wrapped as a single transaction, I'd put the logic in a procedure for cleanliness. You can create a linked server from 2000 to 2005 and refer to the table from there as SERVER.DATABASE.SCHEMA.TABLE. Alternatively you could execute a stored procedure on the remote server to do the insert/update/delete.
If you don't want SQL replication you might instead consider writing the insert/update/deletes from 2000 into a separate table within the same database, via the trigger. Then have a separate job that writes these changes to 2005 then removes them from the table. This would mean you could batch up the changes, mean updates to the original table would be done quicker, would deal better with lost connectivity between the two servers. However, you have less guarantee that the updates would actually be applied to the 2005 server, and you have the added complexity of a sql job that must be run. So it's a tradeoff. And once you start writing and maintaining this sort of logic you realise that's why MS wrote replication stuff, so you don't have to.
It is possible to use linked server and a trigger but I have only bad experiences from this.
Why not use triggers?
Two-way sync with triggers is tricky, because the triggers will fire each other. You will have to control this somehow, for example with special values.
Otherwise, you will get strange locking errors.
You will need to set up MSDTC (Distributed Transaction Coordinator) between linked servers
DBMS can't help you very much with linked servers. it is much harder to debug SQL. Bad queries usually just hang and timeout when there is type mismatch etc.
Transactions with multiple writes in the trigger OR in the query launching the trigger cause deadlocks easily. I would use triggers only to very simple updates (one INSERT/UPDATE/DELETE statement) and even then make sure that deadlocks cannot occur. I remember one integration that I had to rewrite completely when a legacy app caused deadlocks with a trigger.
Alternatives
There are at least two questions to answer:
Is the synch one-way or two-way between tables?
Do the schemas of the two tables match?
If the schemas match, replication should be ideal for both one-way and two-way synch.
If the schemas are different, like usually is the case with application integration (EAI), you might consider:
Integration Services (SSIS) or even Import/Export tool -generated dtsx package
Some other EAI tool, if available (like BizTalk)
programming a custom integration tool
I don't have much experience with EAI tools but comparing SSIS to custom .NET solutions I can only say that you will save a lot of time if you can get the job done with SSIS.
Only if SSIS does not work or is not available (SQL Express) I would try programming a Windows service, WCF service etc.
Yes, you can do this using a linked server and an trigger on the database that is being updated.
SO inside your trigger you would do something like this.
UPDATE linkedserver.Database1.dbo.myTable
SET ...
WHERE ---
with your values for the set and WHERE.
Now, th eonly thing would be how the linked server is setup between 2000 and 2005, you would have to try that out first.