Checking if table exist in database - java

I have a JDBC code which retrieves data from database and get queries at runtime. At runtime, it will go to database and will try to get data and write it to a file. If table is not present it gives exception that table not found. How to handle this?
Here I can not use,
ResultSet rs = md.getTable()
I have to check at runtime only.
SQL Example : select * from table; Preparedstatement and ResultSet here,
At runtime this table variable will get names of table when loop above this will iterate. If table is not there then it gives this exception on console.
How to handle this smoothly?

If you dont want that exception, first you should check what tables are there in the database. If the table doesn't exist you can create and avoid that exception.
DatabaseMetaData dbm = con.getMetaData();
ResultSet tables = dbm.getTables(null, null, "your_table_name", null);
if (tables.next()) {
// Table exists
}
else {
// Table does not exist
}
if the table doesnot exist, you may need to create a new table to avoid such exception later.

with hsqlDB you can do a CREATE TABLE IF NOT EXISTS newTable (column details...) if you only wanted to be sure before creating a new one.

Related

Java - SQLite Database is locked when dropping table

I was trying to delete a column in a SQLite database table using JDBC. As there is no such function in SQLite, to achieve this, I used this approach:
Create a new table (t1_backup) with all columns but not the one to be deleted,
Copy all data (except that of the column to be deleted) to the new table,
Drop the old table (t1),
Rename the new table (t1_backup --> t1).
The actual code is as follows:
Connection cn = DriverManager.getConnection("jdbc:sqlite:"+path);
Statement stmt = new Statement();
stmt = cn.createConnection();
stmt.execute("CREATE TABLE t1_backup(id);");
stmt.executeUpdate("INSERT INTO t1_backup SELECT id FROM t1;");
stmt.execute("DROP TABLE t1;");
stmt.execute("ALTER TABLE t1_backup RENAME TO t1;");
The first two statements were executed without a problem. But when the DROP TABLE statement was executed, it gave me java.sql.SQLException: [SQLITE_LOCKED] A table in the database is locked (database table is locked).
I have found a solution but I was not sure why it worked. The solution is to create three more Statement objects, connect them to the same database and execute each of the four SQL statements with a different Statement object:
stmt.execute("CREATE ...");
stmt2.executeUpdate("INSERT ...");
stmt3.execute("DROP ...");
stmt4.execute("ALTER ...");
Can this be explained?
The JDBC I am using is the one by Xerial.
Thank you.

Delete row from table

I want to delete the current row displayed in jframe from the table contact
I wrote the code
try
{
conn = java.sql.DriverManager.getConnection(connectionURL, "usrnme", "pswd");
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);//also tried with ResultSet.TYPE_SCROLL_SENSITIVE
rs.deleteRow();
rs.next();//it may or may not include in code
}
catch(Exception e){System.out.println( "JDBC error: " + e );}
sql query
String sql="SELECT * FROM contact order by first_name, last_name";
rs=stmnt.executeQuery(sql);
but it throws an exception while running
JDBC error: java.sql.SQLException: 'deleteRow' not allowed because the ResultSet is not an updatable ResultSet.
Help me!
I suggest to do it totally in SQL, where you need to additionally select the (internal) rowid of every row
SELECT c.*, c.rowid FROM contact c ORDER BY first_name, last_name
and afterward delete a row by it row id
DELETE FROM contact c WHERE c.rowid = (?)
this works for Oracle, but every Databasetype does use internal rowid's. For MYSQl you get the rowid by using #rowid as far as I remember
Instead of ResultSet.TYPE_SCROLL_INSENSITIVE, try ResultSet.TYPE_SCROLL_SENSITIVE. That might do the trick. If that doesn't work, try an SQL DELETE statement (w3schools.com) instead to delete the row.
Edit: Now that I reread your code: you need to move to the next row before you call deleteRow. Opening a statement sets the cursor before the first row. If your call to next returns true, your cursor points to the first row. Only if the cursor points to a valid row can you delete the row. HTH.
To make use of updatable ResultSet , your table must contain primary key column. It is the link between data present in ResultSet and DB. Since I infer from your comments your table does not contain primary key, you can delete row using sql query.
String sql = "DELETE FROM contact WHERE first_name='test'";
stmt.executeUpdate(sql);

remove duplicate values while insertion

Hi I am trying to insert values from excel sheet into SQL Database in java. SQL database has already some rows inserted by some other techniques. Now I need to insert new rows from excel sheet and should eliminate the duplicate values which are existed in the database as well as in the excel sheet. For that I write a query like this.
First I inserted the records from excelsheet into SQL database by using insert query
Statement.executeUpdate(("INSERT INTO dbo.Company(CName,DateTimeCreated) values
('"+Cname”' ,'"+ts+"');
Later I deleted the duplicate values using delete query.
String comprows="delete from dbo.Company where Id not in"
+ "(select min(Id) from dbo.Company "
+ "group by CName having count(*)>=1)";
statement3.executeUpdate(comprows);
where Id is autoincremented integer.
but it is not good to do insert and then delete.
How do I know the values are already exist? If it is exist how do I remove during insertion???
You can simply fire a SELECT for the CName first. If a record is found, update else insert a new record.
Edited to add code snippet:
ResultSet rs = Statement.query("SELECT Id from dbo.Company where CNAME = '" +Cname + "'");
if(rs.next()) {
// retrieve ID from rs
// fire an update for this ID
} else {
// insert a new record.
}
Alternatively, if you think that there are already duplicates on your table and you want to remove them as well..
ResultSet rs = Statement.query("SELECT Id from dbo.Company where CNAME = '"+Cname + "'");
List idList = new ArrayList();
while(rs.next()) {
// collect IDs from rs in a collection say idList
}
if(!isList.isempty()) {
//convert the list to a comma seperated string say idsStr
Statement.executeUpdate("DELETE FROM dbo.Company where id in ("+ idsStr + ")");
}
// insert a new record.
Statement.executeUpdate(("INSERT INTO dbo.Company(CName,DateTimeCreated) values('"+Cname”' ,'"+ts+"');
Of course good practice is to use PreparedStatement as it would improve performance.
PS: Excuse me for any syntax errors.
One option would be to create a temp table and dump your Excel data there. Then you can write an insert that joins the temp table with the dbo.Company table and only insert the records that aren't already there.
You could do a lookup on each record you want to insert but if you are dealing with large volumes that's not a super efficient way to do it since you will have to do a select and an insert for each record in you excel spreadsheet.
Merge statements are pretty effective in these types of situations as well. I don't think all databases support them (I know Oracle does for sure). A merge statement is basically a combo insert and update so you can do the look up to the final table and insert if not found and update if found. The nice thing about this is you get the efficiency of doing all of this as a set rather than one record at a time.
If you can control the DB schema, you might consider putting a unique contraint for whatever column(s) to avoid duplicating. When you do your inserts, it'll throw when it tries to add the dup data. Catch it before it tosses you all the way out.
It's usually good to enforce constraints like this on the DB itself; that means no one querying the database has to worry about invalid duplicates. Also, optimistically trying the insert first (without doing a separate select first) might be faster.

Creating a "Java DB" database and associated tables in main checking to see if they exist?

I'm creating an applicaation on Netbeans 7! I'd like my application to have a little code in main so that it can create a Java DB connection checking to see if the database and the associate tables exist, if not create the database and the tables in it. If you could provide a sample code, it'd be just as great! I have already looked at http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javadb/ but I'm still not sure how to check for an existing database before creating it!
I'd like my application to have a little code in main so that it can create a Java DB connection checking to see if the database and the associate tables exist, if not create the database and the tables in it.
You can add the create=true property, in the JDBC URL. This creates a Derby database instance if the database specified by the databaseName does not exist at the time of connection. A warning is issued if the database already exists, but as far as I know, no SQLException will be thrown.
As far as creation of the tables is concerned, this is best done on application startup before you access the database for typical transactional activity. You will need to query the SYSTABLES system table in Derby/JavaDB to ascertain whether your tables exist.
Connection conn;
try
{
String[] tableNames = {"tableA", "tableB"};
String[] createTableStmts = ... // read the CREATE TABLE SQL statements from a file into this String array. First statement is for the tableA, and so on.
conn = DriverManager.getConnection("jdbc:derby:sampleDB;create=true");
for(int ctr =0 ; ctr < tableNames.length; ctr++)
{
PreparedStatement pStmt = conn.prepareStatement("SELECT t.tablename FROM sys.systables t WHERE t.tablename = ?");
pStmt.setString(1, tableNames[ctr]);
ResultSet rs = pStmt.executeQuery();
if(!rs.next())
{
// Create the table
Statement stmt = conn.createStatement();
stmt.executeUpdate(createTableStmts[ctr]);
stmt.close();
}
rs.close();
pStmt.close();
}
}
catch (SQLException e)
{
throw new RuntimeException("Problem starting the app...", e);
}
Any non-existent tables may then be created. This is of course, not a good practice, if your application has multiple versions, and the schema varies from one version of the application to another. If you must handle such a scenario, you should store the version of the application in a distinct table (that will usually not change across versions), and then apply database delta scripts specific to the newer version, to migrate your database from the older version. Using database change management tools like DbDeploy or LiquiBase is recommended. Under the hood, the tools perform the same operation by storing the version number of the application in a table, and execute delta scripts having versions greater than the one in the database.
On a final note, there is no significant difference between JavaDB and Apache Derby.
I don't know how much Oracle changed Derby before rebranding it, but if they didn't change too much then you might be helped by Delete all tables in Derby DB. The answers to that question list several ways to check what tables exist within a database.
You will specify the database when you create your DB connection; otherwise the connection will not be created successfully. (The exact syntax of this is up to how you are connecting to your db, but the logic of it is the same as in shree's answer.)
The create=true property will create a new database if it is not exists. You may use DatabaseMetadata.getTables() method to check the existence of Tables.
Connection cn=DriverManager.getConnection("jdbc:derby://localhost:1527/testdb3;create=true", "testdb3", "testdb3");
ResultSet mrs=cn.getMetaData().getTables(null, null, null, new String[]{"TABLE"});
while(mrs.next())
{
if(!"EMP".equals(mrs.getString("TABLE_NAME")))
{
Statement st=cn.createStatement();
st.executeUpdate("create table emp (eno int primary key, ename varchar(30))");
st.close();;
}
}
mrs.close();
cn.close();
Connection conn = getMySqlConnection();
System.out.println("Got Connection.");
Statement st = conn.createStatement();
String tableName = ur table name ;
String query = ur query;
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
System.out.println("Exist");;
}
catch (Exception e ) {
// table does not exist or some other problem
//e.printStackTrace();
System.out.println("Not Exist");
}
st.close();
conn.close();

How can I detect a SQL table's existence in Java?

How can I detect if a certain table exists in a given SQL database in Java?
You can use DatabaseMetaData.getTables() to get information about existing tables.
This method works transparently and is independent of the database engine. I think it queries information schema tables behind the scenes.
Edit:
Here is an example that prints all existing table names.
DatabaseMetaData md = connection.getMetaData();
ResultSet rs = md.getTables(null, null, "%", null);
while (rs.next()) {
System.out.println(rs.getString(3));
}
Use java.sql.DatabaseMetaData.getTables(null, null, YOUR_TABLE, null). If the table exists, you will get a ResultSet with one record.
See DatabaseMetaData.getTables
For ALL ANSI-compliant databases:
(mySQL, SQL Server 2005/2008, Oracle, PostgreSQL, SQLLite, maybe others)
select 1 from information_schema.tables where table_name = #tableName
This is not a language-specific, but a database-specific problem. You'd query the metadata in the database for the existence of that particular object.
In SQL Server for instance:
SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[table]')
AND type in (N'U')
Write a query that queries the table/view that will list the tables (this is different depending on DB vendor). Call that from Java.
Googling information_schema.tables will help a lot.
Depending on the DB, you can do (MySQL)
SHOW TABLES
or (Oracle)
SELECT * FROM user_objects WHERE object_type = 'TABLE'
or another thing for SQL Server. Cycle through the results for MySQL or further filter on the Oracle one.
Why not just see if it is in sysobjects (for SQL Server)?
SELECT [name] FROM [sysobjects] WHERE type = 'U' AND [name] = 'TableName'
There is a JDBC feature, database vendor independent - see [java.sql.DatabaseMetaData#getTables()][1]
You can get the DatabaseMetaData instance by calling java.sql.Connection#getMetaData()
[1]: http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
This is what worked for me for jdbc:derby:
//Create Staff table if it does not exist yet
String tableName = "STAFF";
boolean exists = conn.getMetaData().getTables(null, null, tableName, null).next();
if(!exists){
s = conn.createStatement();
s.execute("create table staff(lastname varchar(30), firstname varchar(30), position varchar(20),salary double,age int)");
System.out.println("Created table " + tableName);
}
Note that tableName has to be all caps.
For MS Access:
Select Count(*) From MSysObjects
Where type=1 And name='your_table_name_here'

Categories