I have a feeling I'm in a catch-22 situation here, but I'm posting in the hope someone has found a workaround for this at least!
The database for the BIRT reports I work on is being passed in via a hidden parameter called db, so in the data source of my report. So under Property Binding, I tell BIRT to use "jdbc:mysql://localhost/" + params["db"].value as the JDBC Driver URL. This is supposed to use the database name passed in from the URL at runtime in browser, a solution I found online to account for running our reports on computers with different database names.
My issue is that in the same report parameters, the user has to select a company from a list of companies which come from the database. But the report can't populate this list because the database isn't loaded until I press OK on the parameters window, which can't be done until they select a company, and uh-oh I found myself with a catch-22 situation!
I have no idea what I'm suppose to do in this situation, how can I get the report to load the database first, then display the parameters screen based on it?
As far as i know we can't do this because there is no dependency mechanism between two report parameters in BIRT, except cascaded parameters. In this case it means the selected value of parameter "db" is never available when the list of items of "Company" is being evaluated.
Therefore the database should be provided using a different approach. You have a couple options here:
Option 1: Session attribute (if you make use of an application server)
Store the selected database in a user session attribute, and then retrieve it in the property binding of the JDBC URL with an expression such:
reportContext.getHttpServletRequest().getSession().getAttribute("db");
Advantage 1: the database can be different for each user
Advantage 2: the database can be dynamically changed for each user
Drawback: Requires to develop a small servlet allowing to select the database and store it in user session
Option 2: Connection Pool (if you make use of an application server)
This should always be the favorite way to access a JDBC datasource with BIRT. We just have to fill a JNDI URL in the datasource (see your first screen above). The physical database URL and credentials are defined on each application server in a connection pool.
Advantage 1: completely native, nothing specific to be developed
Advantage 2: connection pooling are much more efficient than direct-access JDBC
Advantage 3: connection pooling prevents "Too many connections" issues
Advantage 4: we don't have to hard-code database URL & credentials in reports
Drawback: This JNDI URL is shared by all users.
Visit this article to see an example of using a connection pool with BIRT.
Option 3: Externalize DB in Properties file
As you mentionned database informations can also be externalized in a file.
Advantage 1: we don't have to hard-code database URL & credentials in reports
Advantage 2: we can also develop a small servlet to update this properties file through a GUI
Drawback: This database is shared by all users.
Please check this topic to see how to access a properties file through resources of a report
Option 4: Connection profile store
Advantage: we don't have to hard-code database URL & credentials in reports
Drawback: This database is shared by all users.
Please check this topic to see how to define a connection store
Answering my own question here for the benefit of others. The best solution to this problem is to use an external connection profile property file as described on this stackoverflow thread link. This didn't work for us originally because I couldn't work out how to make the report file look for the properties file regardless of the computer it was run on. However I discovered it is possible to specify an absolute path when loading/saving the properties file (For BIRT 4.4.0 this is under the drop-down beside the browse button under the connection profile of the data source). This allows the the file to be read on any computer once it is saved under the same absolute path.
The other important thing to note is BIRT has a weird habit of changing which of the 3 methods of loading a data source it will use. During our testing we found that if we didn't leave the property bindings settings blank when using a connection profile, BIRT appeared to randomly choose to load via parameter or load via properties file based on which was edited last, very confusing!
Using a parameter to specify the database is still possible, it just has very limited usage. It worked for us up until this point because while we had the database set as a parameter, the same database was always set in the JDBC which the report used to populate the company parameter. But we no longer want to have to set that database manually, now it will be loaded automatically with no problems (hopefully!).
Related
When I click from "Entities from DB" it correctly connects to DB, and it succesfully performs the introspection, so that I can see the list of tables from the side view. But within the popup I get 0 tables, 0 views and 0 mapped relations
0tables
I tried disabling cache and change some settings, and also restarting, but with no luck.
How can I solve the problem?
For MySQL, you need to explicitly specify the schema name in the connection string to make JPA Buddy work.
Even though IntelliJ IDEA allows you to create a data source without specifying a target schema or even a database, JPA Buddy can only get data from an explicitly specified connection string. This limitation comes from the fact that we use JDBC driver to obtain meta information. So, in case your tables are located in the non-default schema, you need to create a new connection targeting the database and schema, as explained here https://www.jpa-buddy.com/documentation/database-connections/#non-default-schema-connection.
I am in charge for migrating old Access 2007 project to MS SQL server 2008 Express. The first stage is to move all the data from MS Access database to SQL server while keeping the Access forms and reports at the client.
So, the data are now moved, an SQL server user (for accessing only that particular database) created, and the tables are linked the Access database via ODBC connection. However, there's one nuisance that should be somehow solved: the Access regularly asks for the user password, when opening the Access database.
The users on server PC and client PC both log onto their local machines, ie their users are not verified on independent domain server.
I see there are several ways how to solve this:
1) Configure the integrated security model so that the user can log on, being automatically authorized by his Windows login (ie, use "trusted connection"). I am not sure how this could be done, given that the server PC does not recognize the user from client PC. If I try to do this now, I get error that the user is connecting from untrusted domain.
2) Store the SQL server user password at client side. I am not sure this is possible, though. I am aware keeping password in some config file, or stored obfuscated in application configuration should be considered lowering security, but this is acceptable for the given setup.
3) Perhaps some other way how to link the SQL server tables into Access?
The best solution is obviously to use Windows security.
If that is not suitable, here is a possible alternative trick, exploiting the fact that Access remembers all opened connections until the program is closed:
copy the connect string of one of your tables
create a passthru queries "ptqConnect" and enter any fast SQL statement in it, like SELECT 1
paste the connect string of into the PTQ Connect property, and make sure you add the PWD=something; in it.
in the startup procedure of your app make sure you call that PTQ. Something like DCount("*", "ptqConnect") will do.
That's it. Since Access remembers opened connections until you close it, even if you close the db, your other tables will now open without any fuss, even if no password is stored in the linked tables Connect string.
If you don't want to expose the connection string that includes the PWD, you could as well initiate a connection from VBA and hide the code by delivering a MDE or just password protecting the code.
You can find an explanation of this behaviour here.
Inform the users your organization's security policy prohibits storing passwords. Therefore they must provide their password each time they open the database. Explain that this policy will deny an unauthorized user the ability to open the database from an authorized user's machine. If the password were stored in any fashion, a miscreant could simply sit down at an unattended machine and open the database.
Since you can't use a trusted connection, this is the safest way to do it. Yes, the users will have to supply their password each time they open the database, but that's what it takes to keep the data safe.
Edit: Since your option #2 is acceptable, you can just store the uid and pwd in the connection strings for the ODBC-linked tables.
Here is an example copied from connectionstrings.com
Driver={SQL Server Native Client 10.0};
Server=myServerAddress;
Database=myDataBase;
Uid=myUsername;Pwd=myPassword;
I split the single line string for browser display. You'll need to also identify which table each of the links points to; examine your current link connection strings to see how that is done.
The uid and pwd will be plain text, and visible to anyone who can view the connection properties. But I didn't see any indication those are concerns for you.
I have had this issue, with Access 2010, linking to SQL Azure, but it was very simple. When linking the tables, there is an tick box option with each table to save the password.
Relinking your tables and checking this option would sort the issue. It does give you warnings that this may not be secure, but not all databases contain confidential data.
Just ran into this problem connecting remotely to my workplace sql server using Access. I have Access 2013, but I don't think it has made any changes to something so basic as as ODBC connection from 2010. Since it is not a trusted connection, yes, you will have to log into the server each time you connect to the database. This is just basic security; can't think why you would ever want an app to just connect from an untrusted network unchallenged. So, I expect to have to log in when opening the database.
What was driving me crazy, however, was that each and every time I tried to open a table, I was asked for the password, and not just once, but twice, and I have to use a 13 character password that was randomly generated at creation! So, needless to say, that was completely unacceptable.
Access keeps the connection information in the sys table MSysOBjects, but I doesn't store the password, at least not there. I use an access DB stored on a cloud server synced with my desktops so I can open a local copy rather than having to remote in to my work desktop. It's much faster this way.
But, using the db in Access as a local file means that I have keep a close eye on the DSN connection names. As long as they are absolutely identical on all computers, it works great. So, if named my DSN "ProductsDBIII" when I created it at work in the ODBC32 Windows tool, then I need to use that same name when creating it at home. The actual connection string will be different, but Access doesn't care about that. However, here's the trick: when I first the DB from home, for instance, after a day at work, then I have to refresh the connections in Access's Linked Table Manager. Just check the tables/views you need, or "Check All", and go. Access will make the connection--probably prompting you for the log in--and then quickly refresh the "connect" string field in the MSysObjects table because they will be different, at least if switching from trusted access.
Voila, no more single or double challenges every frickin' time I open a table. I will get asked once when I first make a connection the first time I open a table from the remote DB, but that's it.
Hope this helps someone.
Jim
Re the use of Passthrough QAuery to set ODBC connection.
The form quoted as the startup form in the Database options will fire BEFORE autoexec.
So that form cannot/should not quote linked tables,
or
Leave that none; and set the form in autoexec.
Otherwise you will still be prompted for pwd for the ODBC connection
A typical problem scenario is using a Switchboard form with the table in the linked database
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.
Basically I need to connect a MySql database to an IOS application and save a local copy to the device but i'm confused about which path I should take to do this.
Here is a basic description of the application:
The application is used to replace multiple paper based forms, allowing the user to complete a desired form on an iPad. Once the user has completed the form, the forms data is uploaded to a server.
Some forms have fields where the user is required to 'select' an option (drop down list). These options need to be pulled from a database because the options will be changed regularly.
The application still needs to work if there is no internet connection!
This means that whenever there is a connection the application needs to save a copy of the current database so that any required information to fill out forms is still available even if there is no connection.
In short my question is: What is my best option to save a local copy of a database (or just a few tables) to an IOS application?
You should look into Core Data. If you're trying to keep an updated copy of a couple tables, I would create a Core Data database that contains the information you need for your app and, every time the user uses your app, check to see if there's an internet connection. If there is, use NSURLSession to download the necessary data from the web server, after which you can compare the downloaded data to that which is in your Core Data database. If there are any discrepancies between the two, you can update your Core Data database as needed. This way you will always have a relatively up-to-date copy of your MySQL database.
This is a good tutorial for getting a feel for NSURLSession in case you haven't used it much.
Hope it helps!
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.