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.
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)
I need to pass datasets from Oracle to Java through JDBC.
How is it better to organize it so that everything works well and it would be convenient both for Java developers and PL/SQL developers to maintain the code in case of changing, for example, table column types?
I see such variants:
Pass the sys_refcursor via stored procedure, and in Java expect that there will be certain fields with a certain type of data.
Pass a strong ref cursor and in Java do the same, that in item 1, but in the PL/SQL package there is a type description.
Pass SQL "table of" type, described at the schema level. If I understand correctly, in Java apparently it can somehow be applied to the object. The problem is that in these types it is impossible to do fields with the column type - Column_Name%TYPE.
Conduct in the PL/SQL package "table of object / record" type, and using JPublisher to work with it - JPublisher apparently converts it into a SQL type. It is not entirely clear for me how this is implemented, and what needs to be done for the same case when the data type of the column changes.
Using the pipelined function instead of the cursor (does this even make sense for such a task?).
What to choose? Or maybe something else, not from these points?
P.S. Sorry for bad English.
I'm not sure that i've understood your queston right, but i think you confused.
The variants, which you discribed is way to execute Java package on server side (for example, when you have database with application servers and want execute java package on it with data of database).
But if you thinking about JDBC then i guess that you want to make some java-app which could work with database. So that you don't have to user some sys_refcursor of subtupes like table of object / record. The JDBC provides capabilities to work with datasets using simple SQL. You should just connect to database as user (via JDBC) and execute sql query. After that you can get any data from result set.
Examples:
Connection example via JDBC
Execute select after connection
So the answer for your question depends on yours goals.
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.
I am trying to Auto create SQL tables on first run, and haven't found any good tutorial on google. Does anyone have a suggestion or can explain it to me. My class so far looks like: http://pastebin.com/6u8yFWrt
In Mysql you can do:
CREATE TABLE tablename IF NOT EXISTS...
This will, as the name says, create the table if there is no table with the same name, described here. If you run it whenever you open the connection to the database, you should be fine.
BUT this is no guarantee that the existing table has the format you want! If you change the definition of the table halfway through the process, because you want an extra column, you will need to delete the existing table fist, for the changes in the query to have an effect.
I think you should use JPA and Hibernate instead. Youre probably in for quite a journey until you get the hold of it but I think it is worth the effort.
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.