Using Apache Derby with Java (J2ME, but I don't think that makes a difference) is there any way of checking if a database already exists and contains a table?
I know of none, except few work around, unlike MySQL where we have that facility of IF EXIST.
What you do is, try to connect to the database, if couldn't its likely its not there. And after a successful connection, you can do a simple select, like SELECT count(*) FROM TABLE_NAME, to know whether the table exist or not. You would be depending on the exception. Even in an official example from Sun, I have seen the similar work around.
In Oracle we have dictionary tables to know about the database objects. I doubt if we have anything like that in Derby.
[Edited]
Well, I found that there is a way to know if the table exist. Try, SELECT tablename FROM SYSTABLES. It is for checking the existence of a table, for checking database you may need to do similar thing, I explained above.
Adeel, you could also use Connection.getMetaData to return a DatabaseMetaData object, then use the getTables, once you have the connection to the database of course. This has the advantage of working for any database with a JDBC driver worth it's salt.
For checking if the database exists, if you are using Derby in the embedded way, or the server is on the same machine, you could check if the folder for the database exists. Is a bit kludgy though. I would do as Adeel suggests and try to connect, catching the exception if it's not there.
I would suggest getting the DatabaseMetaData object, then using the getTables(null, null, null, new String[]{"TABLE"}) method from it, which returns a ResultSet. Use the next() method of the ResultSet, which returns a boolean, to test if any tables exist. If it tests true, you have tables in existence. False, and the database is empty.
Related
I currently have a method in my Java program, using JDBC that checks if a specific table exists in a MySQL database. I had a logic error where the DatabaseMetaData.getTables() method was returning a same-named table from a different database, and I've now solved that by specifying the catalog in the statement as seen below (table represents the table name I'm looking for).
ResultSet tables = connectionToDatabase().getMetaData().getTables("snakeandladder", null, table, null);
However, after doing some research, I saw a lot of people recommending to use Show Tables instead, but not actually explaining why to use Show tables over the above.
Can someone explain to me the limitations of using the statement above and why Show Tables would be a better option?
Thank you!
DatabaseMetaData.getTables() is more portable, most of the databases (not only MySQL) should be able to provide information through defined API.
On the other hand using MySQL specific query "show tables;" may cause more harm than good:
you introduce a query string which can be exploited by an attacker, also the code now contains a statically compiled query string.
if ever the database provider will change, so the code will have to be updated (again portability)
So I've searched around quite a bit and cannot seem to find an answer to this. I have two different applications that speak to the same DB2 database; one uses Hibernate, and the other uses just the native ResultSet, PreparedStatement, etc.
Let's say for example I have an object who's primary key is "ABC". The database has this keys length defined as 3. If I use the spring repositories findOne("ABC"), it returns my object. But the strange thing is if I call findOne("ABC123456"), it will still return that same database row, except the key field in the object is "ABC123456".
Now if I run a native query on the other application using a PreparedStatement, the same thing will happen, except in this case the primary key is returned correctly in the ResultSet.
Assuming this is a DB issue, but not sure what to look at. The database column is setup as a CHAR(3).
I'm trying to access data in multiple databases on a single running instance. the table structures of these databases are all the same; As far as I know, create a new connnection using jdbc is very expensive. But the connection string of jdbc require format like this
jdbc:mysql://hostname/ databaseName, which needs to specify a specific database.
So I'm wondering is there any way to query data in multiple databases using one connection?
The MySQL documentation is badly written on this topic.
The SELECT Syntax page refers to the JOIN Syntax page for how a table name can be written, even if you don't use JOIN clauses. The JOIN Syntax page simply says tbl_name, without further defining what that is. There is even a comment at the bottom calling this out:
This page needs to make it explicit that a table reference can be of the form schema_name.tbl_name, and that joins between databases are therefore posible.
The Schema Object Names page says nothing about qualifying names, but does have a sub-page called Identifier Qualifiers, which says that a table column can be referred to using the syntax db_name.tbl_name.col_name. The page says nothing about the ability to refer to tables using db_name.tbl_name.
But, if you can refer to a column using db_name.tbl_name.col_name, it would only make sense if you can also refer to a table using db_name.tbl_name, which means that you can access all your databases using a single Connection, if you're ok with having to qualify the table names in the SQL statements.
As mentioned by #MarkRotteveel in a comment, you can also switch database using the Connection.setCatalog(String catalog) method.
This is documented in the MySQL Connector/J 5.1 Developer Guide:
Initial Database for Connection
If the database is not specified, the connection is made with no default database. In this case, either call the setCatalog() method on the Connection instance, or fully specify table names using the database name (that is, SELECT dbname.tablename.colname FROM dbname.tablename...) in your SQL. Opening a connection without specifying the database to use is generally only useful when building tools that work with multiple databases, such as GUI database managers.
Note: Always use the Connection.setCatalog() method to specify the desired database in JDBC applications, rather than the USE database statement.
In one of my applications I am providing the users the ability to issue direct SQL queries against a database. They type the SQL text into a text box, then I run it exactly as is using JDBC.
Obviously I trust these users very much. But I would like to limit them programatically to issuing only SELECT statements. They should never DELETE/UPDATE/INSERT. I thought maybe JDBC itself could help me here. I found the executeQuery() method in the java.sql.Statement class. But that method allows me to call DELETE (and maybe UPDATE and INSERT too). It does throw an Exception because no ResultSet is returned, but only after deleting the records.
So, I ask here, is there any way in JDBC to make sure that a SQL statement is only performed if it is a query? Or do I have to parse the statement myself and make sure it complies with my wishes?
I suggest you connect to the DBMS with a user that lacks the DELETE / UPDATE and INSERT permissions.
Something that has been puzzling me for a bit now, and an hour or two of googlin' hasn't really revealed any useful answers on the subject, so I figured I'd just write the question.
When I create a database in SQL using 'CREATE DATABASE DBNAME' am I implicitly creating a catalog in that database? Is it proper to refer to that 'DBNAME' as a catalog? Or is it something completely unrelated?
When I use the MySQL JDBC driver to get the list of tables in a database using the getMetaData() function, the "TABLE_CAT" column (which I would assume means 'catalog') is always set to the name of the database I've choosen.
Coincidence? Or am I just completely wrong on all of this?
catalog is the JDBC term for what many people (and some RDBMs) call databases. i.e. a collection of tables/views/etc. within a database system.