I am getting Operation not allowed after Result Set closed - java

I am extracting about 10,000 patient ids and at the same time after performing encryption I want to insert them in a different table but I am getting this error
java.sql.SQLException: Operation not allowed after ResultSet closed.
Connection conn=null;
PreparedStatement pst=null;
try{
conn = DriverManager.getConnection(constring,username,password);
System.out.println("connected");
Statement stmt=(Statement) conn.createStatement();
ResultSet srs = stmt.executeQuery(
"select patient_id from patient");
while (srs.next()) {
patient_id = srs.getInt("patient_id");
System.out.println(patient_id);
JavaApplication5 o=new JavaApplication5(key);
g=patient_id;
o.c=main.g;
s=o.encrypt(o.c,key);
System.out.println(s);
String insert = "Insert into fyp1 (patient_id) values ('"+s+"')";
stmt.executeUpdate(insert);
}
}
catch(SQLException e){System.out.println(e);

You need to create another Statement since the first ResultSet srs is closed when it is run again at stmt.executeUpdate(insert);.
See in the JavaDocs for ResultSet
Note: A ResultSet object is automatically closed by the Statement object that generated it when that Statement object is closed, re-executed, or is used to retrieve the next result from a sequence of multiple results.
Btw. Please post always the full stacktrace e.g. with the corresponding line numbers.

Related

Multiple Statements in one ResultSet / ResultSet.next() returning false

I am selecting data from two table with two different queries. I am using one connection and one resultset. Both tables are populated but the resultset.next() of the second query is returning false, although it has to be true.
I also tried to use two differend PreparedStatements and Connections but none of this worked out for me.
DataSource ds = null;
Connection c = null;
PreparedStatement ps = null;
String sql = "SELECT * FROM TABLE1"
String sql2 = "SELECT * FROM TABLE2"
ds = // My datasource
c = ds.getConnection();
ps = c.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
// do smth
// works
}
ps.close();
ps = c.prepareStatement(sql2);
resultSet = ps.executeQuery();
while (resultSet.next()) {
// do somth
// does not work although TABLE2 is populated
}
ps.close();
So the program should jump into the second while-loop as there is data returing from the query sql2. Do you have any advise? Thanks!
Try closing the resultset before closing the preparedstatement.
Also, it is very good practice to use try / catch in order to clean things up if you get an exception. See Must JDBC Resultsets and Statements be closed separately although the Connection is closed afterwards?

Can you help me to find the error below in the ResultSet rs=stmt....? [duplicate]

This question already has an answer here:
ResultSet is not for INSERT query? Error message: Type mismatch: cannot convert from int to String
(1 answer)
Closed 5 years ago.
I am getting a error on the resultset rs part where netbeans shows the error as
incompatible types:int cannot be converted to resultset
Class.forName("java.sql.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?useSSL=false", "root", "abc");
Statement stmt = conn.createStatement();
String query = "SELECT * FROM patient WHERE Mobile_No='" + mobno + "';"; /*Get the value from the database*/
ResultSet rs = stmt.executeUpdate(query);/*Part where the error is appearing*/
while (rs.next()) {
String Name = rs.getString("Name");
String Age = rs.getString("Age");
String Mobile = rs.getString("Mobile_No");
String gender = rs.getString("Gender");
String symptoms = rs.getString("Symptoms");
model.addRow(new Object[]{Name, Age, Mobile, gender, symptoms});
}
rs.close();
stmt.close();
conn.close();
Use stmt.executeQuery(String sql), it returns ResultSet.
If you want a ResultSet returned you should use executeQuery, not executeUpdate.
The stmt.executeUpdate(query); doesn't fit for an SELECT query.
You need to replace it by stmt.executeQuery(query);
Well the method executeUpdate returns a int not a results set, seen in the documentation here: https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeUpdate(java.lang.String)
the integer being return being either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements that return nothing
the method you are actually want to use is executeQuery and the documentation for that can be found at:
https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeQuery(java.lang.String)
According the Javadoc (https://docs.oracle.com/javase/9/docs/api/java/sql/Statement.html#executeUpdate-java.lang.String-), stmt.executeUpdate(query); returns an int and not a ResultSet object.
From the Javadoc :
Returns:
either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements that return nothing
I think you must use stmt.executeQuery(query); instead, which return the ResultSet you expect. You're doing a SELECT and not an INSERT, UPDATE, or DELETE operation.
I believe people have already answered your question, which is statement.executeUpdate(query) returns the number of how many rows has been affected by executing the query, and you should use statement.executeQuery(query) instead ..
But this part String query = "SELECT * FROM patient WHERE Mobile_No = '" + mobno + "';" is very bad approach, it will leave the door opened for SQL injection, you should use PreparedStatement instead of Statement

java.sql.SQLException: Operation not allowed after ResultSet closed [help] [duplicate]

When I execute the following code, I get an exception. I think it is because I'm preparing in new statement with he same connection object. How should I rewrite this so that I can create a prepared statement AND get to use rs2? Do I have to create a new connection object even if the connection is to the same DB?
try
{
//Get some stuff
String name = "";
String sql = "SELECT `name` FROM `user` WHERE `id` = " + userId + " LIMIT 1;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
name = rs.getString("name");
}
String sql2 = "SELECT `id` FROM `profiles` WHERE `id` =" + profId + ";";
ResultSet rs2 = statement.executeQuery(sql2);
String updateSql = "INSERT INTO `blah`............";
PreparedStatement pst = (PreparedStatement)connection.prepareStatement(updateSql);
while(rs2.next())
{
int id = rs2.getInt("id");
int stuff = getStuff(id);
pst.setInt(1, stuff);
pst.addBatch();
}
pst.executeBatch();
}
catch (Exception e)
{
e.printStackTrace();
}
private int getStuff(int id)
{
try
{
String sql = "SELECT ......;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
return rs.getInt("something");
}
return -1;
}//code continues
The problem is with the way you fetch data in getStuff(). Each time you visit getStuff() you obtain a fresh ResultSet but you don't close it.
This violates the expectation of the Statement class (see here - http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html):
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.
What makes things even worse is the rs from the calling code. It is also derived off-of the statement field but it is not closed.
Bottom line: you have several ResultSet pertaining to the same Statement object concurrently opened.
A ResultSet object is automatically
closed when the Statement object that
generated it is closed, re-executed,
or used to retrieve the next result
from a sequence of multiple results.
I guess after while(rs2.next()) you are trying to access something from rs1. But it's already closed since you reexecuted statement to get rs2 from it. Since you didn't close it, I beleive it's used again below.

How to assign a Value taken from the database to a label?

I need to assign a string taken by a query from the database to a Jlabel. I tried many methods but failed. How can i do it?
try{
String sql="SELECT MAX(allocationID) FROM allocation where unit='"+ dept + " ' ";
pst=conn.prepareStatement(sql);
String x= (pst.execute());
}
catch(Exception e){
}
Need to study the steps to connect to the database in java First db steps
Get the resultset from the statment by calling ResultSet rs = pst.execute();
Iterate through the list of rows by using the resultset object.
After that assign the value to the JLabel.
You just made several errors in your tiny program, take a look at the code below as an example:
// your way of using prepared statement is wrong.
// use like this
String sql="SELECT MAX(allocationID) FROM allocation where unit=?;";
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
// assign values to the variables in the query string
ps.setString(1, dept);
// execute the query
ResultSet rst = ps.executeQuery();
// parse the result set to get the value
// You'd better do some check here to ensure you get the right result
rst.next();
String x = rst.getInt(1) + "";
ps.close();
conn.close();
}
Have a look at the article if you are interested:https://docs.oracle.com/javase/tutorial/jdbc/basics/retrieving.html

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();

Categories

Resources