Get number of rows updated with PreparedStatement - java

How to get how many rows updated with PreparedStatement?
.getUpdateCount() returns 0.
For executeUpdate got error:
error occurred during batching: batch must be either executed or cleared
my code:
updTrans = dataSource.getConnection().prepareStatement("update...");
updTrans.setInt(1, Integer.valueOf(transaksjonstatusid));
...
updTrans.addBatch();
upd = updTrans.executeUpdate();

You should be using PreparedStatement#executeBatch() when using batches.
...
updTrans.addBatch();
upd = updTrans.executeBatch();
It returns an int[] containing update counts of each batch.

Did you try to use:
int n = preparedStatement.executeUpdate();
Here you can find some explanations on how to use a PreparedStatement.

See The Javadoc
public int executeUpdate()
throws SQLException
Executes the SQL statement in this PreparedStatement object, which must
be an SQL INSERT, UPDATE or DELETE
statement; or an SQL statement that
returns nothing, such as a DDL
statement.
Returns:
either (1) the row count for INSERT, UPDATE, or DELETE statements
or (2) 0 for SQL statements that return nothing
Throws:
SQLException - if a database access error occurs or the SQL
statement returns a ResultSet object

getUpdateCount is meant to be used with the execute(String sql) method. You are probably doing this:
String sql = "UPDATE some_table SET somecolumn = ? WHERE someId = ?";
PreparedStatement ps = connection.prepare(sql);
ps.setString(1, val);
ps.setInt(2, id);
ps.executeUpdate();
In that case you should simply do
int rowsUpdated = ps.executeUpdate();

Related

java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended for INSERT INTO SELECT

I have a below query, which needs to select a row by using a column as key and return generated keys.
INSERT INTO t_tpms_cc_request
(process_identifier,
request_source_id,
amount,
etc_account_id,
retry_count,
status,
store_identifier,
version_no,
next_process_time,
composite_transaction_id,
payment_id,
processed_time,
replenishment_id,
pay_type,
agency_id,
response_code,
file_id,
request_date,
auth_file_id,
auth_date_time,
merc_file_id,
merc_date_time,
cc_num,
cc_expiration_date,
merchant_id,
ext_sys_ref,
encrypt_cc_number,
cc_month_cd,
cc_year_cd,
orig_txn_ref,
auth_code,
avs_code,
cvv_code)
SELECT CC.process_identifier,
CC.request_source_id,
CC.amount,
CC.etc_account_id,
CC.retry_count,
CC.status,
CC.store_identifier,
CC.version_no,
CC.next_process_time,
CC.composite_transaction_id,
CC.payment_id,
CC.processed_time,
CC.replenishment_id,
CC.pay_type,
CC.agency_id,
CC.response_code,
CC.file_id,
CC.request_date,
CC.auth_file_id,
CC.auth_date_time,
CC.merc_file_id,
CC.merc_date_time,
CC.cc_num,
CC.cc_expiration_date,
CC.merchant_id,
CC.ext_sys_ref,
CC.encrypt_cc_number,
CC.cc_month_cd,
CC.cc_year_cd,
CC.orig_txn_ref,
CC.auth_code,
CC.avs_code,
CC.cvv_code
FROM t_tpms_cc_request CC
WHERE CC.order_id = ?
And, I have wrriten a below java code to do this:
String key[] = {"order_id"};
DataSource ds = null;
Connection con = null;
ResultSet rs = null;
try {
ds = jdbcTemplate.getDataSource();
con = ds.getConnection();
PreparedStatement ps =
con.prepareStatement(insertCCRequest.trim(), key);
ps.setString(1, OrderId);
int i= ps.executeUpdate();
rs = ps.getGeneratedKeys();
if (rs.next()) {
return rs.getString(1);
}
} catch (SQLException e) {
logger.debug("SQL exception in RebillDao.insertCCrequest()
method..!! ");
logger.debug("Exception cause: "+e.getMessage());
e.printStackTrace();
throw e;
}
finally {
if(con!=null){
con.close();
}
}
return "";
When i run this, I get below exception:
java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
Please tell me the ways to fix this.
Also, Using JDk 1.6 and ojdbc6-11.2.0.4.jar
I suspect that when you use generated keys with a prepared statement, the Oracle JDBC driver adds the RETURNING INTO clause to the INSERT statement, and that the JDBC driver is too dim to realise that the RETURNING INTO clause can't be used with INSERT INTO ... SELECT ... statements. I get the same ORA-00933 error if I attempt to run an INSERT INTO ... SELECT ... RETURNING ... statement.
What you could try instead is a PL/SQL block where we fetch the 'old' row into a record and then use an INSERT ... VALUES statement with a RETURNING_INTO clause to insert the values into the 'new' row:
DECLARE
l_row t_tpms_cc_request%ROWTYPE;
BEGIN
SELECT * INTO l_row FROM t_tpms_cc_request WHERE order_id = ?;
INSERT INTO t_tpms_cc_request (some_column, some_other_column, ...)
VALUES (l_row.some_column, l_row.some_other_column, ...)
RETURNING order_id INTO ?;
END;
As we're returning values from this, we need to prepare this as a CallableStatement instead of a PreparedStatement, and we need to register parameter 2 as an out parameter. We can then use this out parameter, instead of the getGeneratedKeys() method you're using at the moment, to return the generated key value.
Clearly this approach is Oracle-specific and won't work on other databases. I don't know how much of an issue database portability is to you, nor whether you can return generated keys from an INSERT INTO ... SELECT ... statement in other databases.

SQL Update Maria DB with Prepared Statement

Please help.. I have search it. But I still don't know where is my fault. Maybe I just miss something.
Here is the error :
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?, ID_JABATAN=?, TANGGAL_MASUK=?, TANGGAL_KELUAR=?, ID_JENIS_KARYAWAN=? WHERE ID' at line 1
And this is my code :
try {
DBConnection knk = new DBConnection();
Connection conn = knk.bukaKoneksi();
String sql = "UPDATE KARYAWAN SET NAMA_KARYAWAN=?, ID_JABATAN=?, TANGGAL_MASUK=?, TANGGAL_KELUAR=?, ID_JENIS_KARYAWAN=? WHERE ID_KARYAWAN=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, karyawan.getNamaKaryawan());
ps.setInt(2, karyawan.getIdJabatan());
ps.setDate(3, karyawan.getTanggalMasuk());
ps.setDate(4, karyawan.getTanggalKeluar());
ps.setInt(5, karyawan.getIdJenisKaryawan());
ps.setInt(6, karyawan.getIdKaryawan());
int hasil = ps.executeUpdate(sql);
return hasil > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
And the column of the table :
Try this:
int hasil = ps.executeUpdate();
remove the Parameter from int hasil = ps.executeUpdate(sql);
if you call it with Parameter, the query will be executet, not the prepared Statement.
See the javadoc:
int executeUpdate(String sql)
throws SQLException
Executes the given SQL statement, which may be an INSERT, UPDATE, or
DELETE statement or an SQL statement that returns nothing, such as an
SQL DDL statement. Note:This method cannot be called on a
PreparedStatement or CallableStatement. Parameters:sql - an SQL Data
Manipulation Language (DML) statement, such as INSERT, UPDATE or
DELETE; or an SQL statement that returns nothing, such as a DDL
statement.Returns:either (1) the row count for SQL Data Manipulation
Language (DML) statements or (2) 0 for SQL statements that return
nothingThrows:SQLException - if a database access error occurs, this
method is called on a closed Statement, the given SQL statement
produces a ResultSet object, the method is called on a
PreparedStatement or CallableStatementSQLTimeoutException - when the
driver has determined that the timeout value that was specified by the
setQueryTimeout method has been exceeded and has at least attempted to
cancel the currently running Statement
int executeUpdate()
throws SQLException
Executes the SQL statement in this PreparedStatement object, which
must be an SQL Data Manipulation Language (DML) statement, such as
INSERT, UPDATE or DELETE; or an SQL statement that returns nothing,
such as a DDL statement. Returns:either (1) the row count for SQL Data
Manipulation Language (DML) statements or (2) 0 for SQL statements
that return nothingThrows:SQLException - if a database access error
occurs; this method is called on a closed PreparedStatement or the SQL
statement returns a ResultSet objectSQLTimeoutException - when the
driver has determined that the timeout value that was specified by the
setQueryTimeout method has been exceeded and has at least attempted to
cancel the currently running Statement

Getting resultset from insert statement

i have the below code, where I'm inserting records to a table. When I try to get resultset, it returns null. How to get the latest added row into a resultset?
String sql1 = "INSERT INTO [xxxx].[dbo].[xxxxxx](WORKFLOW_SEQ_NBR," +
" WORKFLOW_LOG_TYPE_CODE, WORKFLOW_STATUS_CODE, DISP_CODE, DISP_USER, DISP_COMMENT, DISP_TITLE, DISP_TS)" +
"VALUES(?,?,?,?,?,?,?,?)";
PreparedStatement pst = connect.prepareStatement(sql1);
pst.setString(1, ...);
pst.setString(2, ...);
...
...
...
pst.executeUpdate();
ResultSet rstest = pst.executeQuery();
// ResultSet rstest = pst.getResultSet();
EDIT: Resolved
added following method to go to the last added row
st.execute("Select * from [xxxx].[dbo].[xxxxxxxxx]");
ResultSet rstest = st.getResultSet();
rstest.afterLast();
GETLASTINSERTED:
while(rstest.previous()){
System.out.println(rstest.getObject(1));
break GETLASTINSERTED;//to read only the last row
}
When using a SQL statement such as INSERT, UPDATE or DELETE with a PreparedStatement, you must use executeUpdate, which will return the number of affeted rows. In this case there is simply no ResultSet produced by the sql operation and thus calling executeQuery will throw a SQLException.
If you actually need a ResultSet you must make another statement with a SELECT SQL operation.
See the javadoc for PreparedStatement#executeQuery and PreparedStatement#executeUpdate
Seems like this is an older question, but i'm looking for a similar solution, so maybe people will still need this.
If you're doing an insert statement, you can use the :
Connection.PreparedStatement(String, String[]) constructor, and assign those to a ResultSet with ps.getGeneratedKeys().
It would look something like this:
public void sqlQuery() {
PreparedStatement ps = null;
ResultSet rs = null;
Connection conn; //Assume this is a properly defined Connection
String sql = "insert whatever into whatever";
ps = conn.prepareStatement(sql, new String[]{"example"});
//do anything else you need to do with the preparedStatement
ps.execute;
rs = ps.getGeneratedKeys();
while(rs.next()){
//do whatever is needed with the ResultSet
}
ps.close();
rs.close();
}
Connection#prepareStatement() - Creates a PreparedStatement object for sending parameterized SQL statements to the database.
which means connect.prepareStatement(sql1); created the PreparedStatement object using your insert query.
and when you did pst.executeUpdate(); it will return the row count for SQL Data Manipulation Language (DML) statements or 0 for SQL statements that return nothing
Now if you again want to fetch the data inserted you need to create a new PreparedStatement object with Select query.
PreparedStatement pstmt = connect.prepareStatement("SELECT * FROM tableName");
then this shall give you the ResultSet object that contains the data produced by the query
ResultSet rstest = pstmt.executeQuery();

PreparedStatement.executeQuery() not returning resultset

I am using preparedStatement to insert data. I am using its executeQuery() method which returns resultSet of data just created by the Query. But I am getting exception saying you should use statement instead of preparedStatement.
Why? What should I do to get the result set? I want to fetch the id of last inserted record which is auto generated.
Any help is appreciated.
You get that exception because you are preparing an Insert (DML) query
to retreive your auto generated key you should create you statement using the following Connection method
PreparedStatement ps = connection.prepareStatement(myQuery,Statement.RETURN_GENERATED_KEYS );
ps.executeUpdate();
ResutSet rs = ps.getGeneratedKeys();
rs.first();
int generatedKey = rs.getInt(1);
I am using preparedStatement to insert data. I am using its executeQuery()
If you are using preparedStatement for inserting then you should not use executeQuery().
Use executeUpdate()
Note
executeUpdate() return int so if you want to check whether inserted or not then do this way
if(executeUpdate()>0)
{
//do some thing
}
{
else
//do somethind
}

Batch processing fails in Oracle. Find out which statement in the batch is causing it

I am extracting data from excel sheet and inserting them into my oracle table. The database is setup in a way that when executing a batch statement, if any insert statement in the batch fails, all the other statements in the batch are not executed. So my problem is how can I find out which row of data is actually causing it, so I can send a message to the user with the row number of the data that's causing the problem?
Connection con = null;
PreparedStatement pstmt = null;
Iterator iterator = list.iterator();
int rowCount = list.size();
int currentRow = 0;
String sqlStatement = "INSERT INTO DMD_VOL_UPLOAD (ORIGIN, DESTINATION, DAY_OF_WEEK, VOLUME)";
sqlStatement += " VALUES(?, ?, ?, ?)";
int batchSize==1000;
for(currentRow=1; currentRow<=rowCount; currentRow++){
ForecastBatch forecastBatch = (ForecastBatch) iterator.next();
pstmt.setString(1, forecastBatch.getOrigin());
pstmt.setString(2, forecastBatch.getDestination());
pstmt.setInt(3, forecastBatch.getDayOfWeek());
pstmt.setInt(4, forecastBatch.getVolumeSum());
pstmt.addBatch();
if(i % batchSize == 0){
updateCounts = pstmt.executeBatch();
con.commit();
pstmt.clearBatch();
session.flush();
session.clear();
}
}
executeBatch returns an integer array containing the counts of all the rows modified by each statement in the batch. I think negative numbers are used to indicate errors. You should be able to figure out which ones failed using this return value.
http://docs.oracle.com/javase/1.3/docs/guide/jdbc/spec2/jdbc2.1.frame6.html
java.sql.Statement's javadoc says that executeBatch() throws BatchUpdateException (a subclass of SQLException) if one of the commands sent to the database fails to execute properly or attempts to return a result set.
The method getUpdateCount() of java.sql.BatchUpdateException "..Retrieves the update count for each update statement in the batch update that executed successfully before this exception occurred..."
If none of this works, you will probably have to fall back to executing and committing each statement (within this particular batch) individually until you hit an error.

Categories

Resources