I am trying to connect MS Access to a MySQL database backend - using the windows "Set up data sources (ODBC)" command allows me to connect to my database fine, but will not save the DSN file for some reason.
I've tried to get around it by manually creating a DSN file which looks like (with the actual data instead of the ***):
[ODBC]
DRIVER=MySQL ODBC 5.1 Driver
USER=****
PASSWORD=****
SERVER=**.***.**.**
DATABASE=cl39-beech
However Access throws up the message
ODBC--call failed.
[microsoft][odbc driver manager] data source name not found and no default driver specified.
Any thoughts on how to get around the problem(s)? I'm not too worried about the first one if I can manually create the DSN file, but need to work out where the second is going wrong!
Simply create the working link from Access like you did in your first step. When the ODBC manager from Access launches then simply create a file data source.
Check that the linked table works by opening the linked table in Access to ensure the connection works and you see data.
Now, simply grab/pull out the connection string saved for that table like this in the debug window (hit ctrl+g to launch VBA IDE and jump to command line).
? currentdb.TableDefs("dbo_customers2").Connect
The debug window will then out put the correct connection string. (so in above, replace what I have with the name of the WORKING linked table).
It is the above connection string result that you can use to re-link a table.
A suggested code example for the above string to re-link tables can be found here.
So don’t bother with trying to use a DSN, as there is often a zillion issues such as where you have to place the file to work etc. The above approach means no DSN is required.
edit:
Edit:
In most cases, you likely don’t need any code. Remember, once you linked the Access tables, then the DSN is in general NOT required. Access linked tables “remember” their settings.
So you really only need such code if you not going to “manually” use the ODBC manager from access to link the tables.
Thus, the code ONLY need to run “one time”. So you on your development machine simply place the code in a standard code module and while in the VBA editor hit F5. As noted, if you ALREADY linked the tables, then you don’t need the DSN anymore anyway (it is only used “during” the re-link process and the settings in that DSN are transferred to each linked tables.
So you don’t need to run the code in some form – it is a “one time” thing you do much like designing a form. You don’t re-design forms on application startup, nor do you need to run some re-link code ONCE the tables have been linked.
In most cases such re-link code is ONLY required if you going to CHANGE the back end database (say from developer back end to the actual production back end database). And thus I suppose you could make a form with a button on it to re-link, but as a general rule you don’t need that code to run each time the application runs.
Once tables are linked then your forms and reports etc. should work as if such tables were regular “local” access tables. So this re-link code is really a “substitute” for you doing the manual linking to the SQL server tables. However ONCE you done a “manual” link, then the original DSN is not required. The re-link code thus in “most” cases is to allow you to re-link the front end database to a back end database of your choice, or in those cases in which you are supporting a client “far away”.
If you are developing “off site” then your linked tables are to your local copy of MySQL. When you send a updated “next great” version of your application to the customer site, then your table links are wrong, and on startup you need to run that re-link code to correctly link the tables to their back end. A “great” way to do this is to ALWAYS have a text file in the same directory as the application. Your application on startup can read that text file, and if the connection string is DIFFERENT then the existing connection, then you call + run your re-link code with this new connection string. Thus you don’t have to be on the customer’s site to roll out updated software. Next time the application runs, the connection strings will match and thus a re-link will NOT be required on startup. So re-linking is a “one time” type of deal here.
There are a BILLION different use cases here. What works for me may well not work for you. It not clear if you are working “on site” (so re-linking of tables is likely NOT required), or you developing off site with your own copy of MySql running (and thus you linked tables point to the wrong server). Or you are developing on site, but DURING development, your front end tables are linked to a “test” copy of the database as to not accidently “mess” with the production data.
So the code belong in a standard (non class) code module. As to when you need to run such code will depending on the billion different possibility’s (so it kind of like asking me to tell you where your shoes are in the morning – I have no idea and never could have an idea). But I can tell you that you should put shoes on when you go outside!
So if your linked tables are now working, then your application should be compiled to a accDE, and then that accDE should be distributed to each computer that requires this application. If they are on the same network etc., then no code or re-linking of the tables is required. On the other hand, if you are developing off site, or the application has to be distributed to several different companies then likely EACH company will have a different server location as to where MySQL is running and thus you need to re-link in each of those cases.
So it is possible that you may well not need ANY re-linking code. If you are “on-site”, then once you linked those tables, then your application should run on ANY computer without needing any re-linking code or having to run this re-link code.
So once tables are “linked”, access remembers that setting and it is permanent.
Related
Can anyone confirm whether linking to tables in a Microsoft Access .accdr files is possible?
I have a split MS-ACCESS application with the frontend in a .accdr file and the tables in an .accdb file backend on a server. For reasons that I explain below, I need the frontend to connect to a table in a second backend file (also on the server) that has an .accdr extension.
I found no documentation that explicitly states that .accdr files are not allowed as as a backend database, however, the linked table manager does not seem to allow it, and the DoCmd.DatabaseTransfer method throws an error.
My workaround is to temporarily rename the .accdr server file as an .accdb, link to the tables in it to make the data changes, then rename it back to .accdr. But if I don't HAVE to do this, I would prefer to connect directly.
Reason:
To make sure that each client gets the most recently updated copy of the frontend .accdr, I created a batch script that first copies the frontend from the server to their local machine before launch. It's a short time penalty (the frontend is about 8 MB) each time they load the application, but the batch script makes sure that the client is ALWAYS up to date. (If performance became an issue I would of course have the batch script verify MD5 sums before downloading, but it hasn't come up yet.)
I don't have many clients connecting at the same time (only about 2 or 3 concurrent connections), but they can connect from any of thousands of computers on campus, so I found this the easiest way to make sure that no matter where they connect from, they will get a fresh copy of the FrontEnd.
Unfortunately, I made a few tables local to the frontend because they allow individual users to set parameters locally during a session. Now, of course, I have a case where an individual user needs to update these local tables so that all the other users will get this same data. (Previously, I had just been making these changes manually upon request, but this user quite reasonably needs to be able to do it herself.)
So, the local frontend .accdr file needs to connect to the server copy of the same frontend .accdr file to make a few data adjustments in a table. That's the reason. I know it's weird.
Thanks,
Damon
Turns out it is possible to use .accdr as a backend. I think i was specifying the wrong connection or something. I used this code snippet with the strConnect = path_to_mydb.accdr:
Public Sub ConnectOutput(dbsTemp As Database, _
strTable As String, strConnect As String, _
strSourceTable As String)
Dim tdfLinked As TableDef
' Create a new TableDef, set its Connect and
' SourceTableName properties based on the passed
' arguments, and append it to the TableDefs collection.
Set tdfLinked = dbsTemp.CreateTableDef(strTable)
tdfLinked.Connect = strConnect
tdfLinked.SourceTableName = strSourceTable
dbsTemp.TableDefs.Append tdfLinked
End Sub
You could easily add the tables that are local to your front-end to the backend. Just copy/paste them from one to the other, delete them from the front-end and link them to the backend version. Takes all of 5 minutes, no VBA code necessary.
Regarding the accdr as a backend question, then yes, accdr is meant to be a open by a the Runtime version of Access. Opening an .accdr file with the standard version of Access simulates the Runtime mode. The only difference between the standard version and the free Runtime version is that you can't access the design tools and the standard ribbon from a Runtime application (you need to create your own).
So renaming a accdb file into accdr only tells access to open the database in Runtime mode. It doesn't change the database itself at all.
So you can use an accdr file as a back-end without problem.
Pro tip: if you want your setup to scale a bit (easily up to 50 concurrent users) and have better performance, open a database to a dummy table from the front-end to the back-end. This will keep the connection open while the front-end is running and keep the lock file open on the database, resulting in better -and more reliable- performance.
I am completely perplexed.
A colleague's got a database issue. I noticed that the (internal) software that created the local database file with the problem, uses programmatic access to MS JET, which meant an easy first step was to see if MS Access (2010) was happy with the database - and then fix, export/import or repair, as a first step.
I copied the stand-alone local Jet data file to a non-networked virtual machine (so no chance of external data), and MS Access opened the db file easily, but I can't make sense of what I'm seeing.
MS Access is configured on that system to show all hidden and system objects, confirmed since the Access system tables in the file are all visible and can be opened. These are my observations:
The object browser lists the usual MS system tables, and a bunch of SELECT queries (which look correct) of the form SELECT (FIELD LIST) FROM (OTHERTABLENAME) WHERE (FIELDNAME=VALUE), nothing more.
The select queries show the usual grid with valid data records when opened, and the data looks correct as well.
No data tables with the given names are showing in the object browser interface.
The given names are listed as objects of the database, in the system table MSysObjects.
So..... the underlying data tables ARE named in MSysObjects, and seem to be true data tables... but they are NOT being listed in the object browser and I can't figure how to open their datasheets (although MS Access' system tables are, and "Show hidden/system" are both enabled)... and the tables surely do exist in the file since an apparent SELECT query is pulling their data from them, and the file is on a clean non-networked machine with no other sources reachable.
Any ideas? I want to check the underlying data but ... whats going on?
When I examined your database, I discovered the reason you can't access the tables normally is because the authors of the internal application which created the db file implemented measures to prevent normal access.
I advise you to contact them and your managers to get authorization and assistance to view the data.
Also, please be cautious with this question. A suspicious person might uncharitably interpret your question as a disguised request for hacking help. Please note I am not accusing you of anything underhanded ... simply asking you to notice how your question might be perceived. And, if that were to happen, I don't know what the consequences would be on Stack Overflow, but I can't imagine it would be good. So please be careful.
I recently developed a simple Access 2010 database for a client. It was designed without VBA, just using macros so it wouldn't trigger any security warnings. The only problem was that it uses ODBC linked tables connected to a SQL Server Express database, and I needed a way to reset the tables' connection strings once installed on my client's computer.
I developed a simple VBscript that goes through the linked tables, copies their names into a dictionary, and then recreates the tables with a new data source:
For Each key In tcmw.Keys
Set td = db.CreateTableDef(key)
td.Connect = "ODBC;Description=xxx;DRIVER=SQL Server;SERVER=xxx\SQLEXPRESS;DATABASE=TCM;User=xxx;Password=xxx;"
td.SourceTableName = key
db.TableDefs.Append td
Next
The script seems to work, but when I hover over the linked tables, I see the following data source. It has Trusted_Connection=Yes instead of the specified username and password:
ODBC;Description=xxx;DRIVER=SQL Server;SERVER=xxx\SQLEXPRESS;Trusted_Connection=Yes
That's not what I set the data source to, and I'm not sure why that would be happening. Is there a step I'm missing to get the username and password saved in the linked table definitions?
I don't know positively but I don't think Access saves the credentials in the connection information. I'm using SQL Server 2008 with an Access 2010 front-end and here's the connection information I see when I hover:
ODBC;Driver=SQL Server Native Client 10.0;SERVER=localhost\SSE2008;APP=Microsoft Office 2010;Database=MyDatabaseName;;TABLE=dbo.SQLTableName
This maybe wouldn't work well for really large projects but I actually run code when the user opens the front end that deletes all of the SQL Server linked tables and recreates them using information that I store in a local table. I'm very happy with how it works but this project only has 22 tables.
I see you mentioned that you use only macros and no VBA in your project. I'm skeptical that you'll be able to make your project work reliably without using some code, at least to handle your linked tables. The way I remember I went the route I did because I had a lot of frustration making linked tables maintain their connection information. In my case I wasn't using Trusted Connections (or Windows authentication). Instead I was using SQL Server authentication which seems to be less resilient when it comes to maintaining connection information without user intervention.
I have created an MS Access 2003 application, set up as a split front-end/back-end configuration, with a user group of about five people. The front end .mdb sits on a network file server, and it contains all the queries, forms, reports, and VBA code, plus links to all the tables in the back end .mdb and some links to ODBC data sources like an AS/400. The back end sits on the same network file server, and it just has the table data in it.
This was working well until I "went live" and my handful of users started coming up with enhancement requests, bug reports, etc. I have been rolling out new code by developing/testing in my own copy of the front-end .mdb in another network folder (which is linked to the same back-end .mdb), then posting my completed file in a "come-and-get-it" folder, alerting the users, and they go copy/paste the new front-end file to their own folders on the network. This way, each user can update their front end when they're at a 'stopping point' without having to boot everyone out at once.
I've found that when I'm developing now, sometimes Access becomes extremely slow. Like, when I am developing a form and attempt to click a drop-down on the properties box, the drop-down arrow will push in, but it will take a few seconds before the list of options appears. Or there's tons of lag in selecting & moving controls on a form. Or lots of keyboard lag.
Then, at other times, there's no lag at all.
I'm wondering if it's because I'm linked to the same back end as the other users. I did make a reasonable effort to set up the queries, forms, reports etc. with minimal record locking, if any at all, depending on the need. But I may have missed something, or perhaps there is some other performance issue I need to address.
But I'm wondering if there is an even better way for me to set up my own development back-end .mdb, so I can be testing my code on "safe" data instead of the same live data as the rest of the users. I'm afraid that it's only a matter of time before I corrupt some data, probably at the worst possible moment.
Obviously, I could just set up a separate back-end .mdb and manually reconfigure the table links in the front end every time, using the Linked Table Manager. But I'm hoping there is a more elegant solution than that.
And I'm wondering if there are any other performance issues I should be considering in this multi-user, split database configuration.
EDIT: I should have added that I'm stuck with MS Access (not MS-SQL or any other "real" back end); for more details see my comment to this post.
If all your users are sharing the front end, that's THE WRONG CONFIGURATION.
Each user should have an individual copy of the front end. Sharing a front end is guaranteed to lead to frequent corruption of the shared front end, as well as odd corruptions of forms and modules in the front end.
It's not clear to me how you could be developing in the same copy of the front end that the end users are using, since starting with A2000, that is prohibited (because of the "monolithic save model," where the entire VBA project is stored in a single BLOB field in a single record in one of the system tables).
I really don't think the problems are caused by using the production data (though it's likely not a good idea to develop against production data, as others have said). I think they are caused by poor coding practices and lack of maintainance of your front end code.
turn off COMPILE ON DEMAND in the VBE options.
make sure you require OPTION EXPLICIT.
compile your code frequently, after every few lines of code -- to make this easy, add the COMPILE button to your VBE toolbar (while I'm at it, I also add the CALL STACK button).
periodically make a backup of your front end and decompile and recompile the code. This is accomplished by launching Access with the /decompile switch, opening your front end, closing Access, opening your front end with Access (with the SHIFT key held down to bypass the startup code), then compacting the decompiled front end (with the SHIFT key held down), then compiling the whole project and compacting one last time. You should do this before any major code release.
A few other thoughts:
you don't say if it's a Windows server. Linux servers accessed over SAMBA have exhibited problems in the past (though some people swear by them and say they're vastly faster than Windows servers), and historically Novell servers have needed to have settings tweaked to enable Jet files to be reliably edited. There are also some settings (like OPLOCKS) that can be adjusted on a Windows server to make things work better.
store your Jet MDBs in shares with short paths. \Server\Data\MyProject\MyReallyLongFolderName\Access\Databases\ is going to be much slower reading data than \Server\Databases. This really makes a huge difference.
linked tables store metadata that can become outdated. There are two easy steps and one drastic one to be taken to fix it. First, compact the back end, and then compact the front end. That's the easy one. If that doesn't help, completely delete the links and recreate them from scratch.
you might also consider distributing an MDE to your end users instead of an MDB, as it cannot uncompile (which an MDB can).
see Tony Toews's Performance FAQ for other generalized performance information.
1) Relink Access tables from code
http://www.mvps.org/access/tables/tbl0009.htm
Once I'm ready to publish a new MDE to the users I relink the tables, make the MDE and copy the MDE to the server.
2) I specifically created the free Auto FE Updater utility so that I could make changes to the FE MDE as often as I wanted and be quite confident that the next time someone went to run the app that it would pull in the latest version. For more info on the errors or the Auto FE Updater utility see the free Auto FE Updater utility at http://www.granite.ab.ca/access/autofe.htm at my website to keep the FE on each PC up to date.
3) Now when working on site at a clients I make the updates to the table structure after hours when everyone is out of the system. See HOW TO: Detect User Idle Time or Inactivity in Access 2000 (Q210297) http://support.microsoft.com/?kbid=210297 ACC: How to Detect User Idle Time or Inactivity (Q128814) http://support.microsoft.com/?kbid=128814
However we found that the code which runs on the timer event must be disabled for the programmers. Otherwise weird things start happening when you're editing code.
Also print preview would sometimes not allow the users to run a menu item to export the report to Excel or others. So you had to right click on the Previewed report to get some type of internal focus back on the report so they could then export it. This was also helped by extending the timer to five minutes.
The downside to extending the timer to five minutes was if a person stays in the same form and at the same control for considerable parts of the day, ie someone doing the same inquiries, the routine didn't realize that they had actually done something. I'll be putting in some logic sometime to reset this timer whenever they do something in the program.
4) In reference to another person commenting about scripts and such to update the schema see Compare'Em http://home.gci.net/~mike-noel/CompareEM-LITE/CompareEM.htm. While it has its quirks it does create the VBA code to update tables, fields, indexes and relationships.
Use VBA to unlink and re-link your tables to the new target when switching from dev to prod. It's been to many years for me to remember the syntax--I just know the function was simple to write.
Or use MS-Access to talk to MS-Access through ODBC, or some other data connection that lives outside of the client mdb.
As with all file base databases, you will eventually run into problems with peak usage or when you go over a small magical number somewhere between 2 and 30.
Also, Access tends to corrupt frequently, so backup, compact and repair need to be done on an frequent basis. 3rd party tools used to exist to automate this task.
As far as performance goes, the data is being processed client side, so you might want to use something like netmeter to watch how much data is going over the wire. The same principle about indexing and avoiding table scans apply to file base dbs as well.
Many good suggestions from other people. Here's my 2 millicents worth. My backend data is on server accessed through a Drive mapping. In my case, the Y drive. Production users get the mapping through a login script using active directory. Then the following scenarios are easily done by batch file:
Develop against local computer by doing a subst command in a batch file
run reports against last nights data by pointing Y to the backup server (read only)
run reports against end of month data by pointing to the right directory
test against specialized scenarios by keeping a special directory
In my environment (average 5 simultaneous users, 1000's of rows, not 10,000's.) corruption has occurred, but it's rare and manageable. Only once in the last several years have we resorted to the previous days backup. We use SQL Server for our higher volume stuff, but it's not as convenient to develop against, probably because we don't have a SQL admin on site.
You might also find some of the answers to this question (how to extract schemas from access) to be useful as well. Once you've extracted a schema using one of the techniques that were suggested you gain a whole range of new options like the ability to use source control on the schemas, as well as being able to easily build "clean" testing environments.
Edit to respond to comment:
There's no easy way to source control an Access database in it's native format, but schema files are just text files like any other. Hence, you can check them in and out of the source control software of your choice for easy version control/rollbacks.
Or course, it relies on you having a series of scripts set up to re-build your database from the schema. Once you do, it's normally fairly trivial to create an option/alternative version that rebuilds it in a different location, allowing you to build test environments from any previous committed version of the schema. I hope that clarifies a bit!
If you want to update the back end MDB schema automatically when you release a new FE to the clients then see Compare'Em http://home.gci.net/~mike-noel/CompareEM-LITE/CompareEM.htm will happily generate the VBA code need to recreate an MDB. Or the code to create the differences between two MDBs so you can do a version upgrade of the already existing BE MDB. It's a bit quirky but works.
I use it all the time.
You need to understand that a shared mdb file for the data is not a robust solution. Microsoft would suggest that SQL Server or some other server based database would be a far better solution and would allow you to use the same access front end. The migration wizard would help you make the changeover if you wanted to go that way.
As another uses pointed out, corruption will occur. It is simply a question of how often, not if.
To understand the performance issues you need to understand that to the server the mdb file with the data in it is simply that, a file. Since no code runs on the server, the server does not understand transactions, record locking etc. It simply knows that there is a file that a bunch of people are trying to read and write simultaniously.
With a database system such as SQL Server, Oracle, DB2. MySQL etc. the database program runs on the server and looks to the server like a single program accessing the database file. It is the database program (running on the server) that handles record locking, transactions, concurrency, logging, data backup/recovery and all the other nice things one wants from a database.
Since a database program designed to run on the server is designed to do that and only that, it can do it far better and more efficently that a program like Access reading an writing a shared file (mdb).
There are two rules for developing against live data
The first rule is . . . never develop
against live data. Not ever.
The second rule is . . .never develop
against live data. Not ever.
You can programatically change the bindings for linked tables, so you can write a macro to change your links when you're deploying a new version.
The application is slow because it's MS Access, and it doesn't like many concurrent users (where many is any number > 1).
My company uses SAI heavily and in order to create reports from this system we use ODBC to connect to the DB. Our setup at the moment is regional and thus we have separate environments for each region. When trying to access these environments using MS ACCESS I am finding that I cannot link to tables in different environments and retrieve accurate data.
I can create the links to various environments using the specific DSN's. I then can access the data, however the first table that I open, no matter the region it belongs to, works fine. After that, however, all of the tables, regardless to the region they belong to, all use the DSN settings from the first table that was opened. If I shut Access down and restart I can then start with data from another environment which will then work, however the rest of the data will then reflect those DSN settings. Additionally, when I look at the property sheet the DSN settings are as they should be.
Let me also add that the tables for each region all have the same name. IE the sales table is sales in all environments, the production table is the production table in all regions. As a result as I link to the sales table from multiple environments the need to be renamed in MS ACCESS.
I would have a look at this SO Question answered a last month.
It describes a couple of methods for forcing Access to re-link ODBC tables and, if all fails, provides you with a way to restart the database programmatically using a small function that you'll find on my blog.
I suspect you leaving out a few details that we need.
When you open that first table, are you prompted for a logon? (this is critical info). If you using “different” links and saving the userid/password in those links, then you should not get any ODBC prompts and you can thus easily work with more than one region.
However, it sounds like you have one set of links, and want to re-point/re-link to a different server. This can work - but NOT if you seeing/allowing ODBC prompts.
If you ARE including the userid/password in the links then you should be able to re-link (switch) to either system. However when you do this, then BOTH uid/password combos ARE and WILL be active at that same given time.
Where things go VERY wrong is that if you re-link with an incorrect logon then the previous uid/password WILL be used! And in fact if you TEST for a logon (even a bad one!), then the first legal logon will be used! At the end of the day, this means the weak point here is WHEN/if you ask for a logon, it WILL return “yes” for a legal logon EVEN if the logon is bad! (because Access will revent to the previous legal logon used) You MUST deal with this issue.
So likely things point to your code that does a logon “test” before re-link. What I would suggest is that your “test” logon code returns OK, you THEN execute a pass-through query to return the database name – if that database name/server is wrong, then you reject that logon and do NOT re-link.
So critical here is how you are testing for the new logon/server? And you most certainly NEVER want the ODBC logon prompt to appear – since if a user cancel, or enters the wrong logon, then your re-link code will use the previous cached logon.
You should be able to re-link the same given set of tables and point them to another server – but you need to ensure that the logon you used did in fact work.
Last but not least:
Access ALWAYS uses a DSN less connection. The ONLY exception is if you are using a system DSN. So when you create a file DSN, and re-link then the DSN FROM THAT point on is ignored, and not used. (this allows you to say distribute the application to other desktops without having to copy/include a DSN). So in effect you near always using a DSN-less connection and if you are not, then I suggest you dump the SYSTEM DSN’s, since Access cannot use the USER/password from such system DSN’s – even if you include the USER/password in that DSN it is STILL ignored.
Also when you re-link, are you using the dbAttachSavePWD – you should not have to, but I would for testing include it.
If you are using/allowing the ODBC driver to prompt the user for a logon – then you have to eliminate this and ensure your code does the logon.
One option you may have (though a bit long winded) would be to create an access database for each region which links to one regions tables. eg have the sales table and production table for region Europe in one access database, and put those from ASIA into another database.
Once you have this set up, you might find it much easier to then use a third access database to link to the two other access databases.
Hope this is useful.