I am wondering, how do I close an executeUpdate statement in JAVA(JDBC)?
For example:
String sql = "UPDATE. .. . .. Whatever...";
ResultSet rs = stmt.executeQuery(sql);
rs.close();
But I couldn't do this to update. So I googled and found out that I need to use executeUpdate but how do I close the statement after?
String sql = "UPDATE. .. . .. Whatever...";
int rs = stmt.executeUpdate(sql);
rs.close(); ??? <------
You don't close the executeUpdate, you close the Statement:
rs.close(); // Closes the ResultSet
stmt.close(); // Closes the Statement
Usually best to do that with a try-with-resources statement:
String sql = "UPDATE. .. . .. Whatever...";
try (
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
) {
// Process results
}
try-with-resources will close both the Statement and the ResultSet for you. It was added in Java 7 (in 2011).
Side note: You've shown that you're using Statement and calling executeUpdate(String). That's fine as long as there's no externally-sourced information in the SQL (nothing you've received from user input or another system, etc.). In the more common case, though, you'd want to use a PreparedStatement, call setXyz to set parameters, and then call executeUpdate() (the zero-args version). This habit keeps you safe from SQL injection. More explanation and examples on this useful site: http://bobby-tables.com/.
Most of the times when you are updating a table you don't get a ResultSet as the result, So no need to close the ResultSet.
Just close the Statement.
Related
Here's my java Code trying to fetch a ResultSet from DB.
try{
ps=conn.prepareStatement(QueryMapper.SCHEDULE_APPLICANT_STATUS);
ps.setString(1,schedule_id);
rs1=ps.execute();
System.out.println(rs1);
ResultSet rs = null;
while(rs1)
{
rs=ps.executeQuery();
System.out.println(rs.next());
Application applicationBean= new Application();
System.out.println("ABC"+schedule_id);
applicationBean.setScheduledProgramId(rs.getString(3));
applicationBean.setStatus(rs.getString(2));
applicationBean.setApplicantId(rs.getString(1));
applicationList.add(applicationBean);
applicationCount++;
}
}catch (SQLException sqlException) {
log.error(sqlException.getMessage());
System.out.println(sqlException.getMessage());
}
When I try to run this, I'm not able to fetch the result set at rs using executeQuery statement. When I tried executing using execute statement it returned true which means some resultset is getting returned. Why is my executeQuery returning null.
The sql query I'm trying to run is
SELECT * FROM APPLICATION WHERE SCHEDULED_PROGRAM_ID=?
This query runs fine and fetch results when executed in sql manager.
Can you tell where I'm doing wrong.
In the code as shown, rs can only be null if rs1 is false, which can only be the case if you are executing something that does not produce a result set (or if your JDBC driver has a bug, but that is less likely).
What you're doing though, makes no sense. If you use execute(), then you should not execute your query again to obtain the result set. Doing that is inefficient, as you're asking the database server to redo the work it did for your first execute(), use getResultSet() instead. As documented on PreparedStatement.execute():
The execute method returns a boolean to indicate the form of the
first result. You must call either the method getResultSet or
getUpdateCount to retrieve the result; you must call
getMoreResults to move to any subsequent result(s).
However, if you know you are executing a query that produces a result set (and a select always produces a result set, even if it is empty!), then you should use executeQuery(). That simplifies your code.
Your code also has an infinite loop. Did you mean to use if (rs1) instead of while(rs1)?
You should change your code to something like
try (PreparedStatement ps=conn.prepareStatement(QueryMapper.SCHEDULE_APPLICANT_STATUS)) {
ps.setString(1,schedule_id);
try (ResultSet rs = ps.executeQuery()) {
// or maybe if (rs.next())?
while (rs.next()) {
Application applicationBean= new Application();
System.out.println("ABC"+schedule_id);
applicationBean.setScheduledProgramId(rs.getString(3));
applicationBean.setStatus(rs.getString(2));
applicationBean.setApplicantId(rs.getString(1));
applicationList.add(applicationBean);
applicationCount++;
}
}
} catch (SQLException sqlException) {
log.error(sqlException.getMessage());
System.out.println(sqlException.getMessage());
}
You don't need two ResultSet objects and you only need to execute the PreparedStatement once. The typical pattern is:
rs = ps.executeQuery();
while (rs.next()) {
// process the row returned by next()
// e.g.,
System.out.println(rs.getString(1));
}
You are missing your reader.
It must be something like: while(rs1.read())
I am new to JDBC and was a bit confused about the syntax. Say I wanted to create multiples queries ( or views in SQL) and refer to a view to make the subsequent queries, how do I do that with prepared statements?
For example:
PreparedStatement first = conn.PreparedStatement("SELECT * FROM clients);
first.execute()
Question Now can I pass the 'PreparedStatement' reference 'first' in the query I am about to create below?
PreparedStatement second = conn.PreparedStatement("SELECT * FROM first WHERE age > 10);
The easiest pattern for JDBC is:
try (PreparedStatement first = conn.prepareStatement(
"SELECT * FROM clients WHERE age BETWEEN ? AND ?")) {
first.setInt(1, 80);
first.setInt(2, 140);
try (ResultSet rs = first.executeQuery()) {
while (rs.next()) {
int age = rs.getInt("age");
...
}
}
}
This syntax: try-with-resources closes first and rs, even if you return or an exception is thrown.
And the statements: first and second are entirely independent.
One does not need to keep the prepared statements open for the entire database session.
The execution is best triggered by executeQuery for SELECT and executeUpdate for UPDATE/INSERT where no ResultSet is yielded.
here is the code there is catch close but i delete it so can anyone replay to me
String id = null;
String root="root",student="root";
String name=jTextField1.getText();
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection
con=(Connection)DriverManager.getConnection
("jdbc:mysql://localhost:3306
/dijlafinal1",root,student);
String query2="SELECT * FROM name WHERE name like ? ";
PreparedStatement pstm2=null;
pstm2=con.prepareStatement(query2);
pstm2.setString(1,"%"+name+"%");
ResultSet rs = pstm2.executeQuery(query2 );
while (rs.first()){
String name1=rs.getString("name");
id= rs.getString("id");
int epo =rs.getInt("epo");
}
jTextField2.setText(id);
}
You need to use the no-argument version of executeQuery(), i.e.
ResultSet rs = pstm2.executeQuery();
The reason is that you've already prepared the statement when you called con.prepareStatement(query2). Calling executeQuery(query2) will throw away the prepared SQL and execute the query without bind variables, leaving the ? in place -- as the error message suggests.
When working with a PreparedStatement you always call the .execute... methods without any arguments because you have already supplied the SQL command text with the .prepareStatement call. So
ResultSet rs = pstm2.executeQuery(query2 );
is incorrect. You need to simply do
ResultSet rs = pstm2.executeQuery();
I wonder if it might work if you use this?
pstm2.setString(1,"'%"+name+"%'");
If I create a statement with JDBC and execute a query, do I need to close said statement and create a new one before executing again? Eclipse doesn't complain about the second case.
try {
connection = dataSource.getConnection();
try {
statement = connection.createStatement();
statement.execute("set search_path to '...'");
} finally {
Utils.tryClose(statement);
}
try {
statement = connection.createStatement();
statement.execute("SET statement_timeout TO " + (QUERY_TIMEOUT_SECONDS * 1000));
} finally {
Utils.tryClose(statement);
}
try {
statement = connection.createStatement();
statement.execute(query);
} finally {
Utils.tryClose(statement);
}
} finally {
Utils.tryClose(connection);
}
As opposed to:
try {
connection = dataSource.getConnection();
statement = connection.createStatement();
statement.execute("set search_path to '...'");
statement.execute("SET statement_timeout TO " + (QUERY_TIMEOUT_SECONDS * 1000));
statement.execute(query);
} finally {
Utils.tryClose(statement);
Utils.tryClose(connection);
}
That is not required you can use the same statement to query the DB multiple times, the only thing to remember is that each resultset returned with a statement execution will be closed after creating a new statemnet. Quoting from java docs:-
By default, only one ResultSet object per Statement object can be open at the same time. Therefore, if the reading of one ResultSet object is interleaved with the reading of another, each must have been generated by different Statement objects. All execution methods in the Statement interface implicitly close a statment's current ResultSet object if an open one exists.
Hence you can do something like this:-
try {
connection = dataSource.getConnection();
statement = connection.createStatement();
ResultSet rs1=statement.execute("....");
//parse rs1
//close rs1
ResultSet rs2= statement.execute(....);
//parse rs1
//close rs1
} finally {
Utils.tryClose(statement);
Utils.tryClose(connection);
}
I am not sure why eclipse is complaining in case of PreparedStatements, the whole purpose of PreparedStatements is to define a query structure and execute the query multiple times by only changing the parameters. For example when you want to parse and insert a large text file into DB. Quoting from javadocs
If you want to execute a Statement object many times, it usually reduces execution time to use a PreparedStatement object instead.
It is possible to Use two query with in single ResultSet
A result set corresponds to a single SQL query. However your "single" query could use UNION to effectively combine more than one query.
No you should not do this.
For example
ResultSet rs = null;
Statement stmt1 = con.createStatement("Query1");
Statement stmt2 = con.createStatement("Query2");
rs = stmt1.executeQuery();
while(rs.next()){
}
//Here result set should be closed before assigning new result set to "rs" variable like
stmt1.close();
rs.close();
rs = stmt2.executeQuery();
You should close old result set before using it again. If you don't close the old resultset object then it will be in memory and never be garbage collected.
If you close the DB connection object in this case(without closing resultset properly) then connection object is not garbage collected(not retuned to pool) as connection have reference(i.e. unclosed resultset).