Sequential JDBC statement executions not transacting - java

I have the following tables:
all_app_users
=============
all_app_user_id INT PRIMARY KEY NOT NULL
is_enabled BOOLEAN NOT NULL
myapp_users
===========
myapp_user_id INT PRIMARY KEY NOT NULL
all_app_user_id INT FOREIGN KEY (all_app_users)
myapp_user_stage INT NOT NULL
And the following JDBC code:
Long allAppUserId = null;
Long myAppId = null;
Connection pooledConn = getPooledDBConnection();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = pooledConn.prepareStatement("INSERT INTO all_app_users ( is_enabled ) VALUES ( ? )");
ps.setBoolean(1, true);
ps.execute();
ps.close();
ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('all_app_users')");
rs = ps.executeQuery();
allAppUserId = (long)rs.getInt(0);
rs.close();
ps = pooledConn.prepareStatement("INSERT INTO myapp_users ( all_app_user_id, myapp_user_stage ) VALUES( ?, ? )");
ps.setInt(1, Ints.checkedCast(allAppUserId));
ps.setInt(2, 5);
ps.execute();
ps.close();
ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('myapp_users')");
rs = ps.executeQuery();
myAppId = (long)rs.getInt(0);
pooledConn.commit();
System.out.println("Ping");
} catch(SQLException sqlExc) {
logger.error(ExceptionUtils.getStackTrace(sqlExc));
if(pooledConn != null) {
try {
pooledConn.rollback();
} catch (SQLException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
} finally {
try {
if(rs != null) {
rs.close();
}
if(ps != null) {
ps.close();
}
if(pooledConn != null) {
pooledConn.close();
}
} catch (SQLException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
System.out.println("Pong");
When I run that code, I don't get any exceptions, and the "Ping" and "Pong" messages print to STDOUT, however myAppId is NULL. I'm wondering why?
Perhaps it has to do with my use of transactions/commits? Should I be committing after each of the 4 sequential SQL statements? Am I using the JDBC API incorrectly?

Unlike SCOPE_IDENTITY, IDENT_CURRENT does not care about transactions or scope: it returns the last identity key that has been generated for the table.
IDENT_CURRENT can return NULL when the table has no identity column, never contained rows, or has been truncated. None of this applies in your situation. However, it looks like you are running the scalar query incorrectly: you never call rs.next() before calling rs.getInt(...):
ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('all_app_users')");
rs = ps.executeQuery();
rs.next(); // <<== Add this line
allAppUserId = (long)rs.getInt(0);
rs.close();
ps = pooledConn.prepareStatement("INSERT INTO myapp_users ( all_app_user_id, myapp_user_stage ) VALUES( ?, ? )");
ps.setInt(1, Ints.checkedCast(allAppUserId));
ps.setInt(2, 5);
ps.execute();
ps.close();
ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('myapp_users')");
rs = ps.executeQuery();
rs.next(); // <<== Add this line
myAppId = (long)rs.getInt(0);

Related

Invalid column index for JDBC insert with sequence number

Below is my code:
I'm passing three parameters to method insertRecordIntoTable which will execute JDBC insert query but I'm receiving Invalid column index.
Below are log statements which got printed:
Inside insertRecordIntoTable
ID from sequence 14
Invalid column index
private static void insertRecordIntoTable(String userName, String targetEmail, String siteName) throws SQLException {
Connection dbConnection = null;
PreparedStatement preparedStatement = null;
System.out.println("Inside insertRecordIntoTable ");
String insertTableSQL = "insert into TableName values(?,?,?,?,?)";
try {
dbConnection = getDBConnection();
preparedStatement = dbConnection.prepareStatement(insertTableSQL);
ResultSet srs = preparedStatement.executeQuery("SELECT id_seq.NEXTVAL FROM dual");
if ( srs!=null && srs.next() ) {
int myId = srs.getInt(1);
System.out.println("ID from sequence "+myId);
preparedStatement.setInt(1, myId);
System.out.println("Inserted ID value "+myId);
srs.close();
}
preparedStatement.setString(2, userName);
System.out.println("Inserted username value "+userName);
preparedStatement.setString(3, targetEmail);
System.out.println("Inserted targetEmail value "+targetEmail);
preparedStatement.setString(4, siteName);
System.out.println("Inserted sitecode value "+siteName);
preparedStatement.setTimestamp(5, getCurrentTimeStamp());
System.out.println("Inserted date value "+getCurrentTimeStamp());
preparedStatement .executeUpdate();
System.out.println("Inserted values ");
System.out.println("Inserted name & email into the table...");
// execute insert SQL stetement
preparedStatement.executeUpdate();
System.out.println("Record is inserted into DBUSER table!");
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (preparedStatement != null) {
preparedStatement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}
}
You are using the same PreparedStatement variable twice
preparedStatement.executeQuery("SELECT id_....);
Create and use another variable for this Query else the original Query will be overwritten.
Also consider what is going to happen if
if ( srs!=null && srs.next() ) {
returns false

Using jdbc I am using oracle plsql function to retrieve result set, it is not giving me all records in java

CallableStatement stmt = null;
String sql = "begin ? := TEST.USER_LIST.queryByUser(?,?,?,?); end;";
ResultSet rs = null;
try {
stmt = conn.prepareCall(sql);
stmt.registerOutParameter(1, OracleTypes.CURSOR);
stmt.setString(2, "user1"); stmt.setInt(3, 1); // offset
stmt.setString(4, "Update_Date"); stmt.setString(5, "DESC");
stmt.execute();
if(stmt.getObject(1)==null) {
System.out.println("Null value");
} else {
rs = (ResultSet) stmt.getObject(1);
int i = 0;
while (rs.next()) { i++; }
System.out.println("rs size: " +i);
stmt.close();
rs.close();
}
} catch (Exception ex) {
} finally {
try { rs.close(); stmt.close();
} catch (Exception ex) {}
}
OUTPUT:
rs size: 19
PROBLEM: Total rows return by this code is 10 less than rows in db
if 50 rows in db it shows 40, if 30 it shows 20, if 9 its shows 0.
You need one of ResultSet (rs) types: ResultSet.TYPE_SCROLL_INSENSITIVE
or ResultSet.TYPE_SCROLL_SENSITIVE for that to work
Usually you count the ResultSet starting from rs.beforeFirst() so you count the first element to.
int size = 0 ;
if (rs != null){
rs.beforeFirst();
rs.last();
size = rs.getRow();
}
My suggestion is to make a SELECT COUNT(*) inside the stored procedure
Found the problem, it was ojdbc jar issue, was using ojdbc6, now have replaced with ojdbc14. after jar change it is working fine, Thanks all for reply.

When I try o insert data dataexecuteQuery() isn't working?

Can't seem to fix this. Been trying to get it to work for the past hour. any help would be appreciated.
INFO: Server startup in 868 ms
java.sql.SQLException: Can not issue data manipulation statements with executeQuery().Event{id=0, name='dads', venue='dasd', startDate='11/11/11', endDate='12/11/11'}
Seemed to be getting an error when I try to do an insert.
public void addEvent(Event event) throws DaoException{
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = this.getConnection();
String query = "INSERT INTO TABLE EVENT VALUES(null, ?, ?, ?, ?)";
ps = con.prepareStatement(query);
ps.setString(1, event.getName());
ps.setString(2, event.getVenue());
ps.setString(3, event.getStartDate());
ps.setString(4, event.getEndDate());
rs = ps.executeQuery();
}catch(SQLException e) {
System.out.println(event.toString());
e.printStackTrace();
}finally {
try {
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
if (con != null) {
freeConnection(con);
}
} catch (SQLException e) {
throw new DaoException("Couldn't " + e.getMessage());
}
}
}
for inserting or updating or deleting you should use executeUpdate()
executeUpdate() returns int value
so replace this line rs = ps.executeQuery(); with
int result = ps.executeUpdate();
Note you will get another error after modifying as per above because you sql query is also wrong
Use the following query
INSERT INTO EVENT VALUES(null, ?, ?, ?, ?)
it looks like incorrect syntax of INSERT Query, update it likewise
INSERT INTO EVENT VALUES(null, ?, ?, ?, ?) // remove TABLE word
//INSERT INTO TABLE_NAME VALUES(...) , this is correct syntax.
also correct here too
executeUpdate() instead of executeQuery()
// for insert/update/delete query always use executeUpdate(),
// for select query use executeQuery()

java.sql.SQLException: ResultSet is from UPDATE. No Data.

(the Stored Procedure runs perfectly in MySQL Workbench and also retrieves the Rows)
Here is My Code :
ConnectionManager cm = new ConnectionManager();
java.sql.CallableStatement cstmt = null;
try
{
connect = cm.getConnection();
connect.createStatement();
String SQL = "{call getReportDetails ('"+ emailId +"','"+password+"')}";
cstmt = connect.prepareCall(SQL);
rs = cstmt.executeQuery(SQL);
int i = 0;
while(rs.next())
{
String element1 = rs.getString("description");
// -- some code --
}
}
catch(Exception e)
{
e.printStackTrace();
}
Delete the line with createStatement.
And (the error) do not use SQL as parameter of executeQuery.
(The overloaded version with an sql parameter is for the immediate, non-prepared statement version.)
Further close statement and result set; try-with-resources will do nice here.
try (CallableStatement cstmt =
connect.prepareCall"{call getReportDetails (?, ?)}")) {
cstmt.setString(1, emailId);
cstmt.setString(2, password);
try (ResultSet rs = cstmt.executeQuery()) {
int i = 0;
while (rs.next())
{
String element1 = rs.getString("description");
// -- some code --
}
}
}
In the general case for stored functions you might need to specify the result yourself:
cstmt.registerOutParameter(1, Types.INTEGER);
cstmt.registerOutParameter(2, Types.VARCHAR);
rs.getString(2);
But here you have a ResultSet.
CallableStatement cs = null;
try {
cs = connectionObject.prepareCall("{call getReportDetails (?, ?)}");
cs.setString(1, emailId);
cs.setString(2, password);
cs.execute();
ResultSet rs = cs.getResultSet();
while (rs.next()) {
System.out.println(rs.getString("columnLabel"));
}
}
catch (SQLException e) {
e.printStackTrace();
}
finally{
//close statements
}

java.sql.SQLException: Can not issue data manipulation statements with executeQuery() [duplicate]

This question already has answers here:
Cannot issue data manipulation statements with executeQuery()
(11 answers)
Closed 6 years ago.
I can't seem to work out the bug. I need the ResultSet though to get the actual Object. The error is: java.sql.SQLException: Can not issue data manipulation statements with executeQuery(). at rs = pst.executeQuery();. Code:
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
String url = null; //Set, but not visible in code.
String user = null; //Set, but not visible in code.
String password = null; //Set, but not visible in code.
public Object get(String table, String key){
try {
con = DriverManager.getConnection(url, user, password);
String query = "SELECT * FROM `" + table + "` WHERE key = ?;";
pst = con.prepareStatement(query);
pst.setString(1, key);
pst.executeUpdate();
rs = pst.executeQuery();
rs.next();
return rs.getObject(1);
} catch (SQLException ex) {
return null;
} finally {
try {
if (rs != null) {
rs.close();
}
if (pst != null) {
pst.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
return null;
}
}
}
donot use executeQuery use executeUpdate that your sql statement is
between (update,insert,delete) see
https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeUpdate(java.lang.String)

Categories

Resources