Ignore exception and continue to insert the rest of the data - java

I have the following codes snippet. I remove further details. I have a for loop with all the data in it. The I run the for loop for (int i = 0; i < list.getLength(); i++). What happens is that the moment any one of the data cause the sql with error say the data has a slash etc then it cause exception and the rest of the for loop cant continue. How can I like skip the one with the exception and continue with rest?
Here is a the codes.
Connection dbconn = null;
Statement stmt1 = null;
Statement stmt2 = null;
try
{
dbconn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test1", "tes1", "te15");
stmt1 = dbconn.createStatement();
stmt2 = dbconn.createStatement();
DateFormat outDf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = Calendar.getInstance().getTime();
String value = null;
for (int i = 0; i < list.getLength(); i++)
{
String insertCommand = "INSERT INTO command SET .........";
System.out.println("\n SET INSERT :" + insertCommand);
int count = stmt1.executeUpdate(insertCommand);
}
}
catch (SQLException ex)
{
System.out.println("MyError Error SQL Exception : " + ex.toString());
}
catch (Exception rollback)
{
System.out.println("\nRollback :");
rollback.printStackTrace(System.out);
}
catch (Exception e)
{
System.out.println("\n Error here :");
e.printStackTrace(System.out);
}
finally
{
try
{
if (stmt1 != null)
{
stmt1.close();
}
}
catch (SQLException ex)
{
System.out.println("MyError: SQLException has been caught for stmt1 close");
ex.printStackTrace(System.out);
}
try
{
if (stmt2 != null)
{
stmt2.close();
}
}
catch (SQLException ex)
{
System.out.println("MyError: SQLException has been caught for stmt2 close");
ex.printStackTrace(System.out);
}
try
{
if (dbconn != null)
{
dbconn.close();
}
else
{
System.out.println("MyError: dbConn is null in finally close");
}
}
catch (SQLException ex)
{
System.out.println("MyError: SQLException has been caught for dbConn close");
ex.printStackTrace();
}
}

You need to put the try/catch block inside the for, around executeUpdate(insertCommand);

You need to catch the error in the loop too
....
for (int i = 0; i < list.getLength(); i++) {
try {
String insertCommand = "INSERT INTO command SET .........";
System.out.println("\n SET INSERT :" + insertCommand);
int count = stmt1.executeUpdate(insertCommand);
} catch (Exception e) {
// Better catch the real exception
// Handle the exception
}
}
....

Related

Kill Sybase processes using batch with java jdbc

I used Java to create a simple database process killer by sending a kill command in a loop. I want to know if I can use batch with kill command in one call:
try(Connection dbCon = GetDBConnection()){
try (Statement st = dbCon.createStatement();) {
dbCon.setAutoCommit(false);
for (int i = 0; i < processes.length; i++) {
st.addBatch("kill " + processes[i]);
}
st.executeBatch();
dbCon.commit();
dbCon.setAutoCommit(true);
}
catch (Exception e) {
System.out.println("Error SQL killing process: " + e);
}
catch (Exception e) {
System.out.println("Error opening connection: " + e);
}
I have the chance to try it and worked.
I have add some little changes to validate if it is only one process make a normal kill, and if it get more than one, then use batch.
try (Connection dbCon = GetDBConnection(); Statement st = dbCon.createStatement();) {
String queryKill = "kill ";
if (spids.length > 1) {
dbCon.setAutoCommit(false);
for (int i = 0; i < spids.length; i++) {
st.addBatch(queryKill + spids[i]);
System.out.println(queryKill + spids[i]);
}
st.executeBatch();
dbCon.commit();
dbCon.setAutoCommit(true);
} else {
queryKill = queryKill + spids[0];
System.out.println(queryKill + spids[0]);
st.execute(queryKill);
}
} catch (Exception e) {
killed = false;
System.out.println("Error SQL killing process: " + e);
}

How to bypass the initializing for a ResultSet?

So this is part of my code :
try {
for (int i = 0; i < n; i++){
ResultSet res;
res = bdd.requete(sql);
doSomethingWithRes()
}
}
catch (Exception e) {
e.printStackTrace();
}
I would like to close the resultSet at the end of this block (to save resources), however if I add res.cose(), java will tell me that res may not have been initialized (which is true for n=0). Is there a way to initialize the resultSet without doing a query ?
I also tried
try {
for (int i = 0; i < n; i++){
ResultSet res;
res = bdd.requete(sql);
doSomethingWithRes()
}
}
catch (Exception e) {
e.printStackTrace();
}
if (n>=1)
res.close()
but the compiler doesn't accept it, even though it would work. Is there a way to force the compiler to accept this ?
You would have to increase the scope of the ResultSet instance; only issue is you have more than one and you should close all of them. I would suggest a try-with-resources like
try {
for (int i = 0; i < n; i++){
try (ResultSet res = bdd.requete(sql)) {
doSomethingWithRes();
}
}
}
catch (Exception e) {
e.printStackTrace();
}

APOSTROPHE issue with java and SQL

I have code, where I have single quote or APOSTROPHE in my search
I have database which is having test table and in name column of value is "my'test"
When running
SELECT * from test WHERE name = 'my''test';
this works fine
If I use the same in a Java program I am not getting any error or any result
But If I give the name with only single quote then it works
SELECT * from test WHERE name = 'my'test';
Could you please help me out to understand.
Java code is
Connection con = null;
PreparedStatement prSt = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.
getConnection("jdbc:oracle:thin:#localhost:1521:orcl"
,"user","pwd");
String query = "SELECT * from "
+ "WHERE name = ? ";
prSt = con.prepareStatement(query);
String value = "my'mobile";
char content[] = new char[value.length()];
value.getChars(0, value.length(), content, 0);
StringBuffer result = new StringBuffer(content.length + 50);
for (int i = 0; i < content.length; i++) {
if (content[i] == '\'')
{
result.append("\'");
result.append("\'");
}
else
{
result.append(content[i]);
}
}
prSt.setObject(1, result.toString());
int count = prSt.executeUpdate();
System.out.println("===============> "+count);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally{
try{
if(prSt != null) prSt.close();
if(con != null) con.close();
} catch(Exception ex){}
}
You don't have to escape anything for the parameter of a PreparedStatement
Just use:
prSt = con.prepareStatement(query);
prSt.setString("my'mobile");
Additionally: if you are using a SELECT statement to retrieve data, you need to use executeQuery() not executeUpdate()
ResultSet rs = prst.executeQuery();
while (rs.next())
{
// process the result here
}
You might want to go through the JDBC tutorial before you continue with your project: http://docs.oracle.com/javase/tutorial/jdbc/index.html

SQL executeBatch slow processing

Basically i have to read a csv file and perform some validation.
If duplicate record is found i've to delete the previous record and insert the latest 1.
The file contains about 100k records. I'm not sure what I'm doing wrongly but it's taking way too long to load the data.
public static ArrayList<BootstrapMessage> loadLocation(File file) {
ArrayList<BootstrapMessage> errors = new ArrayList<BootstrapMessage>();
CSVReader reader = null;
Connection conn = null;
Connection conn2 = null;
PreparedStatement pstmt = null;
PreparedStatement ps = null;
try {
conn = ConnectionManager.getConnection();
conn2 = ConnectionManager.getConnection();
conn.setAutoCommit(false);
pstmt = conn.prepareStatement(INSERT_LOCATION);
ps = conn2.prepareStatement("delete from location where `timestamp` = ? AND mac_address = ?");
reader = new CSVReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
reader.readNext();//header
String[] record = reader.readNext();
int counter = 2;//starting from line 2. Line 1 is header
int validRecords = 0;
while (record != null) {
ArrayList<String> message = null;
//try {
message = ValidatorUtil.validateLocation(record, file.getName(), counter);
if (message != null) {//contains error
errors.add(new BootstrapMessage(file.getName(), counter, message));
} else {//valid record
String key = record[0] + record[1];
if (locations.containsKey(key)) {//duplicate found.
pstmt.executeBatch();
message = new ArrayList<String>();
message.add("duplicate row");
errors.add(new BootstrapMessage(file.getName(), locations.get(key), message));
//delete record from database
ps.setTimestamp(1, Timestamp.valueOf(record[0]));
ps.setString(2, record[1]);
ps.executeUpdate();
//inserting the latest record
pstmt.setTimestamp(1, Timestamp.valueOf(record[0]));
pstmt.setString(2, record[1]);
pstmt.setInt(3, Integer.parseInt(record[2]));
pstmt.addBatch();
if (validRecords % 2000 == 0) {
pstmt.executeBatch();
}
} else {
pstmt.setTimestamp(1, Timestamp.valueOf(record[0]));
pstmt.setString(2, record[1]);
pstmt.setInt(3, Integer.parseInt(record[2]));
pstmt.addBatch();
validRecords++;
if (validRecords % 2000 == 0) {
pstmt.executeBatch();
}
}
}
if (validRecords > 0) {
pstmt.executeBatch();
conn.commit();
}
record = reader.readNext();
counter++;
}
System.out.println("valid location records = " + validRecords);
//numOfValidRecords.put(fileName, validRecords);
if (!errors.isEmpty()) {
return errors;
}
} catch (FileNotFoundException ex) {
Logger.getLogger(LocationDAO.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(LocationDAO.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(LocationDAO.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
Logger.getLogger(LocationDAO.class.getName()).log(Level.SEVERE, null, ex);
}
}
ConnectionManager.close(conn2, ps);
ConnectionManager.close(conn, pstmt);
}
return null;
}
Why don't you use native database loaders to do the job?
Or I would first insert all the records into staging and then do the duplicate removals by using the database tools, either SQL or some database procedure. This way it has to be faster.

How to deal with null value in table column in java?

I am getting null pointer exception again and again while getting value from database table.....why its giving me null pointer exception?
Here is my code :
private HashSet getPlayerList() {
HashSet hs = new HashSet();
String soccername = "";
try {
conn = ConnectionProvider.getConnection();
rs = null;
pstmt = null;
String sql = "Select * from Players where deleted = false";
if (conn != null) {
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while (rs.next()) {
soccername = rs.getString("soccername").trim();// this line giving exception
if (soccername == null || soccername.isEmpty()) {
soccername = rs.getString("name").trim();
}
hs.add(soccername);
}
}
} catch (NamingException ex) {
System.out.println(ex);
} catch (SQLException ex) {
System.out.println(ex);
} finally {
try {
pstmt.close();
rs.close();
conn.close();
} catch (SQLException ex) {
System.out.println(ex);
}
}
return hs;
}
that is wrong:
soccername = rs.getString("soccername").trim();// this line giving exception
if (soccername == null || soccername.isEmpty()) {
if rs.getString("soccername") returns null it must leads to a NPE because it is followed by the function trim().
better is:
soccername = rs.getString("soccername");
if (soccername == null || soccername.trim().isEmpty()) {
It should be:
soccername = rs.getString("soccername");
if (soccername == null || soccername.isEmpty()) {
soccername = rs.getString("name").trim();
} else {
//now you are sure that soccername is not null
soccername = soccername.trim();
}

Categories