unable to drop table in HSQLDB - java

I am unable to drop table with default user SA(or any user for that matter) in HSQLDB even though I can create table and read them without problem, please see my code below, what's wrong?
On the other hand, If I use a third party SQL client(eg. squirrel), I can login and drop table without problem even when user is empty.
public static void main(String[]args){
try {
DBManager.executeUpdate("drop table mytable");
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public static Connection getConnection(){
Connection c =null;
try {
c = DriverManager.getConnection("jdbc:hsqldb:file:e:\\xxx_db\\xxx", "SA", "");
} catch (SQLException ex) {
ex.printStackTrace();
}
return c;
}
public static int executeUpdate(String s) throws SQLException {
Connection con = getConnection();
try{
return con.createStatement().executeUpdate(s);
}
finally{
if(con!=null)try {
con.close();
} catch (SQLException ex) {
Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

It turns out I need to do an explicit shutdown aftwards
DBManager.executeUpdate("shutdown");

Try committing after executing the DDL.

Related

rollback mysql transcations from multiplate methods GWT

I'm trying to figure out how to rollback commits from multiple methods. I want to do something like the following (editing for brevity)
public void testMultipleMethodRollback() throws DatabaseException {
Connection conn = connect();
fakeMethodRollback1();
fakeMethodRollback2();
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
and currently all my methods are formatted like this
public void fakeMethodRollback1() throws DatabaseException {
Connection con = connect();
PreparedStatement ps = null;
ResultSet rs = null;
// insert some queries
try {
String query = "some query";
ps = conn.prepareStatement(query);
ps.executeUpdate(query);
query = "some query";
ps = conn.prepareStatement(query);
ps.executeUpdate(query);
con.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
throw new DatabaseException(e);
} finally {
close(rs, ps, conn);
}
}
because I want to be able to use the other methods independently, how can I do a rollback where if one method fails, the others will roll back? I fear I have my whole class setup wrong or at least wrong enough that this can't be accomplished without major work. I can't change the methods to return a connection, because half of my methods are get methods, which are already returning other data. Any ideas?

combination of Oracle database and in-memory database in java program

I am going to enhance the performance of my program. For this purpose I am going to implement some parts of my program to be done in memory instead of database. I dont know which one is better in this regards, in-memory database or normal java data structure.For in-memory database I considered Tentimes from oracle and H2. So another question would be which solution is better for around 100 million records of data on single machine for single user? Also another question would be is the old way of database connection works fine in this way? Here is the connection that I used for oracle, What is the appropriate Driver for this purpose.
public static Connection getConnection(){
//If instance has not been created yet, create it
if(DatabaseManager.connection == null){
initConnection();
}
return DatabaseManager.connection;
}
//Gets JDBC connection instance
private static void initConnection(){
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
String connectionUrl = "jdbc:oracle:thin:#localhost:1521:" + dbName;
DatabaseManager.connection =
DriverManager.getConnection(connectionUrl,"****","****");
}
catch (ClassNotFoundException e){
System.out.println("Oracle driver is not loaded!");
System.exit(0);
}
catch (SQLException e){
System.out.println(e.getMessage());
System.exit(0);
}
catch (Exception e){
}
}
public static ResultSet executeQuery(String SQL) throws SQLException
{
CachedRowSetImpl crs = new CachedRowSetImpl();
ResultSet rset = null ;
Statement st = null;
try {
st = DatabaseManager.getConnection().createStatement();
rset = st.executeQuery(SQL);
crs.populate(rset);
}
catch (SQLException e) {
System.out.println(e.getMessage());
System.exit(0);
}finally{
rset.close();
st.close();
}
return crs;
}
public static void executeUpdate(String SQL)
{
try {
Statement st = DatabaseManager.getConnection().createStatement();
st.executeUpdate(SQL);
// st.close();
}
catch (SQLException e) {
System.out.println(e.getMessage());
System.exit(0);
}
}
Regards.

java.sql.SQLException: ORA-01000: maximum open cursors exceeded while truncating tables

I get this exception while truncating all table in a schema.
I truncate 3 schema in my Java code and first method get list of table names from given schema name and second method executes "TRUNCATE TABLE table_name" query.
I confused about my code always succesful while truncating first and third schema. But while executing on second schema I get ORA-01000 error.
My truncate code is
private void truncateTable(Connection conn, String tableName) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(Utility.TRUNCATE_TABLE + tableName);
ps.executeUpdate();
} catch (SQLException e) {
log.error("SQLException occured while getting table names from schema", e);
} finally {
Utility.free(ps, null, null);
}
}
private List<String> getAllTableNames(Connection conn) {
PreparedStatement ps = null;
ResultSet rs = null;
List<String> list = new ArrayList<String>();
try {
ps = conn.prepareStatement(Utility.SELECT_ALL_TABLE_NAMES);
rs = ps.executeQuery();
while (rs.next()) {
list.add(rs.getString("TABLE_NAME"));
}
} catch (SQLException e) {
log.error("SQLException occured while getting table names from schema", e);
} finally {
Utility.free(ps, rs, null);
}
return list;
}
public static void free(PreparedStatement ps, ResultSet rs, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
log.error("Error occurred while closing ResultSet",e);
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
log.error("Error occurred while closing PreparedStatement",e);
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
log.error("Error occurred while closing Connection",e);
}
}
}
What is the wrong about code or is it about schema configuraiton in Oracle?
How can I solve this?
If are you iterating over the List generated by getAllTableNames and calling truncateTable in a tight loop, your free calls in the finally block might just be delayed and stacking up to an extent that they aren't clearing fast enough for the next iterations - since you only know the finally will be called at some point, not necessarily immediately and before control is returned to the caller.
The schema size would make a difference to that, so it might make sense that a small schema succeeds and a large one fails. If that is what's happening then you should call free inside the try, as well as in the finally:
private void truncateTable(Connection conn, String tableName) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(Utility.TRUNCATE_TABLE + tableName);
ps.executeUpdate();
Utility.free(ps, null, null);
ps = null;
} catch (SQLException e) {
log.error("SQLException occured while getting table names from schema", e);
} finally {
if (ps != null) {
Utility.free(ps, null, null);
}
}
}
If Utility.free checks whether ps is null then that check in the finally block might be redundant, but without it, free would be called twice if there is no SQLException.
Check out the code and make sure you are closing the cursors after being used. If the problem still persists please set OPEN_CURSORS to some more value.

Is that the best way to release SQLite connection in Java?

I need a good way to close SQLIte connections in Java. After a few suggestion by other users I decided to add to my code a finally block to be sure that closing operation are always executed.
public static boolean executeQuery(String query)
{
Connection conn = null;
Statement stmt = null;
try
{
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection(Global.dbPath);
stmt = conn.createStatement();
stmt.execute(query);
return true;
}
catch(ClassNotFoundException e)
{
System.out.println(e);
return false;
}
catch(SQLException e)
{
System.out.println(e);
return false;
}
finally
{
try
{
stmt.close();
conn.close();
return true;
}
catch (SQLException ex)
{
System.out.println ("Errore closing connections");
return false;
}
}
}
I'm not sure that this is the best solution.
How can I optimize this for readability?
A few comments; nutshells:
Separate the SQL exceptions from the reflection exception.
Are your SQL exceptions recoverable? If not, throw an app-specific RuntimeException.
Wrap up the connection and statement close exceptions in a utility method, yours or a 3rd party's.
Don't short-change exception handling; dump the stack trace.
This leads to the following:
public static boolean executeQuery(String query) {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
throw new DbException("Could not find JDBC driver", e);
}
Connection conn = null;
Statement stmt = null;
try {
conn = DriverManager.getConnection(Global.dbPath);
stmt = conn.createStatement();
stmt.execute(query);
return true;
} catch(SQLException e) {
throw new DbException("Exception during statement execution", e);
} finally {
DbUtils.closeQuietly(conn);
DbUtils.closeQuietly(stmt);
}
}
(I'm using Apache Commons' DbUtils for its closeQuietly, it checks for null (yours didn't). Your own version might throw an app-specific exception as I do here with DbException. This wraps up all your DB-related exceptions into a single exception class, which may or may not be what you need.
If you want to make sure a command is executed you have to put it alone into a try catch block:
try {
stmt.close();
}
catch (Exception ex) {
}
try {
conn.close();
}
catch (Exception ex) {
System.out.println ("Error closing connections");
return false;
}

Multiple Insert Query in Oracle

I had requirement to perform two insert queries in two different tables.
I am using Oracle/Java Combination.
What are the options available in this case?
If you're trying to insert the same data into two separate tables you can use a multitable insert like this:
insert all
into table1(a, b)
into table2(a, b)
select 1 a, 2 b from dual;
The most straightforward method is to do two inserts sequentially using the same connection. Assuming that part of your point is that you want the two inserts to occur in the same transaction, then make sure you have disabled autocommit on the connection, and explicitly commit after the second insert.
Another option would be to write an Oracle stored procedure that does the inserts, and call it from Java with a PreparedStatement.
Sample from devdaily.
package com.devdaily.sqlprocessortests;
import java.sql.*;
public class BasicJDBCDemo
{
Connection conn;
public static void main(String[] args)
{
new BasicJDBCDemo();
}
public BasicJDBCDemo()
{
try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://localhost/coffeebreak";
conn = DriverManager.getConnection(url, "username", "password");
doTests();
conn.close();
}
catch (ClassNotFoundException ex) {System.err.println(ex.getMessage());}
catch (IllegalAccessException ex) {System.err.println(ex.getMessage());}
catch (InstantiationException ex) {System.err.println(ex.getMessage());}
catch (SQLException ex) {System.err.println(ex.getMessage());}
}
private void doTests()
{
doSelectTest();
doInsertTest(); doSelectTest();
doUpdateTest(); doSelectTest();
doDeleteTest(); doSelectTest();
}
private void doSelectTest()
{
System.out.println("[OUTPUT FROM SELECT]");
String query = "SELECT COF_NAME, PRICE FROM COFFEES";
try
{
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next())
{
String s = rs.getString("COF_NAME");
float n = rs.getFloat("PRICE");
System.out.println(s + " " + n);
}
}
catch (SQLException ex)
{
System.err.println(ex.getMessage());
}
}
private void doInsertTest()
{
System.out.print("\n[Performing INSERT] ... ");
try
{
Statement st = conn.createStatement();
st.executeUpdate("INSERT INTO COFFEES " +
"VALUES ('BREAKFAST BLEND', 200, 7.99, 0, 0)");
}
catch (SQLException ex)
{
System.err.println(ex.getMessage());
}
}
private void doUpdateTest()
{
System.out.print("\n[Performing UPDATE] ... ");
try
{
Statement st = conn.createStatement();
st.executeUpdate("UPDATE COFFEES SET PRICE=4.99 WHERE COF_NAME='BREAKFAST BLEND'");
}
catch (SQLException ex)
{
System.err.println(ex.getMessage());
}
}
private void doDeleteTest()
{
System.out.print("\n[Performing DELETE] ... ");
try
{
Statement st = conn.createStatement();
st.executeUpdate("DELETE FROM COFFEES WHERE COF_NAME='BREAKFAST BLEND'");
}
catch (SQLException ex)
{
System.err.println(ex.getMessage());
}
}
}
You can check with StoredProcedures and execute with PreparedStatement in JDBC api. That intern will return you two resultSets , which you can get with a method getMoreResults(). You can then process the resultsets separately.

Categories