I was stuck with the error , here my line number 42 is while(rs.next()){, please help me with this i am stuck at this for few hrs.
> Exception in thread "main" java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:937)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:872)
at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:740)
at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:6326)
at removeStopwords.RemoveStopwords.main(RemoveStopwords.java:42)
This is my code:
package removeStopwords;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.StringTokenizer;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
public class RemoveStopwords {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/mydbv2";
// Database credentials
static final String USER = "root";
static final String PASS = "***";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Connection conn = null;
Statement stmt = null;
Class.forName("com.mysql.jdbc.Driver");
conn = (Connection) DriverManager.getConnection(DB_URL, USER, PASS);
stmt = (Statement) conn.createStatement();
String sql;
ResultSet rs = null;
ResultSet rs2 = null;
ResultSet rs3 = null;
java.sql.PreparedStatement ps = null;
int event_id = 10;
sql = "SELECT id,text from tweet where event_id = " + event_id;
rs = stmt.executeQuery(sql);
String text = "";
Long id;
while (rs.next()) {
id = rs.getLong("id");
text = rs.getString("text");
System.out.println("tweet = " + text);
text = text.replaceAll("http[^\\s]+", "");
text = text.replaceAll("www[^\\s]+", "");
System.out.println("tweet after removal of links= " + text);
StringTokenizer st = new StringTokenizer(text);
while (st.hasMoreTokens()) {
String stopword = st.nextToken();
System.out.println("stopword : " + stopword);
sql = "SELECT * from stopwords WHERE word =" + '"'+stopword+'"';
rs2 = stmt.executeQuery(sql);
if (rs2.next()) {
text = text.replaceAll(stopword, "");
System.out.println("tweet after removing stopword = " + text);
}
sql = "SELECT * from filtertweet where tweet_id = " + id + "";
rs3 = stmt.executeQuery(sql);
if (!rs3.next()) {
sql = "INSERT INTO filtertweet VALUES(?,?)";
ps = conn.prepareStatement(sql);
ps.setLong(1, id);
ps.setString(2, text);
ps.executeUpdate();
}
}
}
stmt.close();
conn.close();
}
}
A Statement object can have only one active ResultSet, so when you execute rs2 = stmt.executeQuery(sql), the first ResultSet (rs) gets closed.
Create two Statement objects, one for rs and another for rs2.
Quoting the javadoc of Statement:
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.
One ResultSet for one Statement is valid. When you are executing multiple queries use various Statements.
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Connection conn = null;
Statement stmt = null;
Class.forName("com.mysql.jdbc.Driver");
conn = (Connection) DriverManager.getConnection(DB_URL, USER, PASS);
stmt = (Statement) conn.createStatement();
String sql;
ResultSet rs = null;
ResultSet rs2 = null;
ResultSet rs3 = null;
java.sql.PreparedStatement ps = null;
int event_id = 10;
sql = "SELECT id,text from tweet where event_id = " + event_id;
rs = stmt.executeQuery(sql);
String text = "";
Long id;
while (rs.next()) {
id = rs.getLong("id");
text = rs.getString("text");
System.out.println("tweet = " + text);
text = text.replaceAll("http[^\\s]+", "");
text = text.replaceAll("www[^\\s]+", "");
System.out.println("tweet after removal of links= " + text);
StringTokenizer st = new StringTokenizer(text);
while (st.hasMoreTokens()) {
String stopword = st.nextToken();
System.out.println("stopword : " + stopword);
sql = "SELECT * from stopwords WHERE word =" + '"'+stopword+'"';
Statement stmt2 = conn.createStatement();
rs2 = stmt2.executeQuery(sql);
if (rs2.next()) {
text = text.replaceAll(stopword, "");
System.out.println("tweet after removing stopword = " + text);
}
sql = "SELECT * from filtertweet where tweet_id = " + id + "";
Statement stmt3 = conn.createStatement();
rs3 = stmt3.executeQuery(sql);
if (!rs3.next()) {
sql = "INSERT INTO filtertweet VALUES(?,?)";
ps = conn.prepareStatement(sql);
ps.setLong(1, id);
ps.setString(2, text);
ps.executeUpdate();
}
}
}
stmt.close();
conn.close();
}
JDBC does not allow you to close the Statement that created the ResultSet or to execute another query that creates a ResultSet using the same Statement. Create different Statement objects and Resultset objects, make sure to not use the same Statement objects to execute two different Resultset statements.
Related
This question already has answers here:
Java JDBC MySQL exception: "Operation not allowed after ResultSet closed"
(2 answers)
Closed 6 years ago.
I am trying to run following code but getting error:
SQL Exception thrown: java.sql.SQLException: Operation not allowed
after ResultSet closed.
How to resolve this error? I need two result sets for my application.
public static void main(String[] args) {
String connectionUrl = "jdbc:mysql://127.0.0.1:3306/test";
String dbUser = "root";
String dbPwd = "Syntel#92";
Connection conn;
ResultSet rs, res1 = null;
Statement stmt = null;
int rowcount = 0;
// String queryString = "create table job_status_table as select j1.job_id,s1.Source_ID,s1.Source_name from JOb_list j1,SOURCE_DETAILS s1 where s1.Source_ID = j1.Source_ID";
String queryString = "create table job_status_table as select source_id,source_name from source_details";
String addcolumn = "alter table job_status_table add column Source_rowcount int";
String fetchdata = "Select Source_name from job_status_table";
try {
conn = DriverManager.getConnection(connectionUrl, dbUser, dbPwd);
stmt = conn.createStatement();
// get record count from table job_status_table1
// stmt.executeQuery("select count() from job_status_table1");
// create table
stmt.executeUpdate(queryString);
System.out.println("Table created in the database");
stmt.executeUpdate(addcolumn);
System.out.println("alter table");
rs = stmt.executeQuery(fetchdata);
System.out.println("fetch data");
while (rs.next()) {
String table_count = null;
String table_name = null;
table_name = rs.getString("Source_name");
System.out.println(table_name);
// table_name = rs.getString("Source_name");
//System.out.println(table_name);
//rs.close();
table_count = "select count(*) from " + table_name;
//table_count = "select count(*) from " + table_name;
//rs.close();
// res1 = stmt.executeQuery(table_count);
res1 = stmt.executeQuery(table_count);
//System.out.print(res1);
if (res1.next()) {
rowcount = res1.getInt(1);//res1.getInt(1);
System.out.println("Result set values" + rowcount);
} else {
System.out.println("value is not present in resultset");
}
System.out.println("Get Row Count");
System.out.println(table_count);
// int cnt = rcnt(table_count);
String updaterow = "update job_status_table set Source_rowcount ="
+ rowcount
+ " where Source_name = '"
+ table_name
+ "'";
System.out.println("updateoutput" +stmt.executeUpdate(updaterow));
System.out.println("Update Complete");
}
/* if (conn != null) {
rs.close();
res1.close();
stmt.close();
conn.close();
conn = null;
}
*/
}
catch (SQLException sqle) {
System.out.println("SQL Exception thrown: " + sqle);
}
}
}**
You could try this:
First copy the ResultSet rs in an ArrayList and close it.
Iterate over the ArrayList and close res1 before the update.
And I don't think the else with "value is not present in resultset" is reachable, but if you should set the rowcount to 0.
EDIT
After reading the referenced question the second time:
The problem is the reusing of stmt for res1 and the update
I am Using the following code :
DefaultListModel dModel = (DefaultListModel)jList1.getModel();
txtBilln.enableInputMethods(false);
try{
Class.forName("com.mysql.jdbc.Drvier");
Connection con = (Connection)
DriverManager.getConnection("jdbc:mysql://localhost:3306/jns","root","jns");
Statement stmt = null ;
ResultSet rs = null ;
String SQL = "SELECT * FROM ELEB";
stmt = con.createStatement();
rs = stmt.executeQuery(SQL);
while (rs.next()){
String bno= rs.getString("billn");
String cnamme = rs.getString("cname");
dModel.addElement(bno + "-" + cnamme);
}
jList1.setModel(dModel);
con.close();
}catch(Exception e){
JOptionPane.showMessageDialog(this, e.getMessage());
e.printStackTrace();
}
I'm a MySQL user and I have been using following statements in MySQL Workbench :
(these statements are based on Select column names whose entries are not null)
SET group_concat_max_len = 4294967295;
SELECT GROUP_CONCAT(
' SELECT ',QUOTE(COLUMN_NAME),
' FROM ( select * from table_name where s3_01 = ', coloumn1,' ) abc',
' WHERE `',REPLACE(COLUMN_NAME, '`', '``'),'` IS NOT NULL',
' HAVING COUNT(*)'
SEPARATOR ' UNION ALL ')
INTO #sql
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'table_name';
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Although it work in my workbench, I do not know how to make it work in java.
for example, I made following code:
String sql1 = "SET group_concat_max_len = 4294967295;";
String sql2 = " SELECT GROUP_CONCAT(' SELECT ',QUOTE(COLUMN_NAME), ' FROM ( select * from ptc_weight where s3_01 = ',column1,' ) abc', ' WHERE `',REPLACE(COLUMN_NAME, '`', '``'),'` IS NOT NULL', ' HAVING COUNT(*)' SEPARATOR ' UNION ALL ') INTO #sql FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ptc_weight'; ";
String sql3 = " PREPARE stmt FROM #sql; ";
String sql4 = " EXECUTE stmt;";
String sql5 = " DEALLOCATE PREPARE stmt;";
String[] result = getResult(sql1+sql2+sql3+sql4+sql5);
public static String[][] getResult(String sql) {
System.out.println(sql);
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
String[][] resultTable = null;
try {
con = getCon();
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
ResultSetMetaData result = rs.getMetaData();
int rowNum=0;
// Go to the last row
rs.last();
rowNum = rs.getRow();
// Reset row before iterating to get data
rs.beforeFirst();
int colNum = result.getColumnCount();
resultTable = new String[rowNum][colNum];
for(int itr1=0; itr1<rowNum; itr1++){
rs.next();
for(int itr2=0; itr2<colNum; itr2++){
resultTable[itr1][itr2] = rs.getObject(itr2+1).toString();
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
dbclose(con, ps, rs);
}// finally
return resultTable;
}
However, it does not work. I guess I made a wrong code for utilizing stored procedure, but I don't have any idea to deal with this problem.
CallableStatement callableStatement = null;
String getDBUSERByUserIdSql = "{call getDBUSERByUserId(?,?,?,?)}";
callableStatement.setInt(1, 10);
callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
callableStatement.registerOutParameter(3, java.sql.Types.VARCHAR);
callableStatement.registerOutParameter(4, java.sql.Types.DATE);
// execute getDBUSERByUserId store procedure
callableStatement.executeUpdate();
String userName = callableStatement.getString(2);
String createdBy = callableStatement.getString(3);
Date createdDate = callableStatement.getDate(4);
System.out.println("UserName : " + userName);
System.out.println("CreatedBy : " + createdBy);
System.out.println("CreatedDate : " + createdDate);
Here Is Full Example. You can modify your code as you need.
Simple one with less argument and with resultset :
CallableStatement cstmt = con.prepareCall("{call getEmployeeDetails(?, ?)}");
cstmt.setInt("employeeId", 123);
cstmt.setInt("companyId", 456);
ResultSet rs = cstmt.executeQuery();
I created a database with one table in MySQL:
CREATE DATABASE iac_enrollment_system;
USE iac_enrollment_system;
CREATE TABLE course(
course_code CHAR(7),
course_desc VARCHAR(255) NOT NULL,
course_chair VARCHAR(255),
PRIMARY KEY(course_code)
);
I tried to insert a record using Java:
// STEP 1: Import required packages
import java.sql.*;
import java.util.*;
public class SQLInsert {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/iac_enrollment_system";
// Database credentials
static final String USER = "root";
static final String PASS = "1234";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
Scanner scn = new Scanner(System.in);
String course_code = null, course_desc = null, course_chair = null;
try {
// STEP 2: Register JDBC driver
Class.forName("com.mysql.jdbc.Driver");
// STEP 3: Open a connection
System.out.print("\nConnecting to database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
System.out.println(" SUCCESS!\n");
// STEP 4: Ask for user input
System.out.print("Enter course code: ");
course_code = scn.nextLine();
System.out.print("Enter course description: ");
course_desc = scn.nextLine();
System.out.print("Enter course chair: ");
course_chair = scn.nextLine();
// STEP 5: Excute query
System.out.print("\nInserting records into table...");
stmt = conn.createStatement();
String sql = "INSERT INTO course " +
"VALUES (course_code, course_desc, course_chair)";
stmt.executeUpdate(sql);
System.out.println(" SUCCESS!\n");
} catch(SQLException se) {
se.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
if(stmt != null)
conn.close();
} catch(SQLException se) {
}
try {
if(conn != null)
conn.close();
} catch(SQLException se) {
se.printStackTrace();
}
}
System.out.println("Thank you for your patronage!");
}
}
The output appears to return successfully:
But when I select from MySQL, the inserted record is blank:
Why is it inserting a blank record?
no that cannot work(not with real data):
String sql = "INSERT INTO course " +
"VALUES (course_code, course_desc, course_chair)";
stmt.executeUpdate(sql);
change it to:
String sql = "INSERT INTO course (course_code, course_desc, course_chair)" +
"VALUES (?, ?, ?)";
Create a PreparedStatment with that sql and insert the values with index:
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, "Test");
preparedStatement.setString(2, "Test2");
preparedStatement.setString(3, "Test3");
preparedStatement.executeUpdate();
this can also be done like this if you don't want to use prepared statements.
String sql = "INSERT INTO course(course_code,course_desc,course_chair)"+"VALUES('"+course_code+"','"+course_desc+"','"+course_chair+"');"
Why it didnt insert value is because you were not providing values, but you were providing names of variables that you have used.
This should work for any table, instead of hard-coding the columns.
//Source details
String sourceUrl = "jdbc:oracle:thin:#//server:1521/db";
String sourceUserName = "src";
String sourcePassword = "***";
// Destination details
String destinationUserName = "dest";
String destinationPassword = "***";
String destinationUrl = "jdbc:mysql://server:3306/db";
Connection srcConnection = getSourceConnection(sourceUrl, sourceUserName, sourcePassword);
Connection destConnection = getDestinationConnection(destinationUrl, destinationUserName, destinationPassword);
PreparedStatement sourceStatement = srcConnection.prepareStatement("SELECT * FROM src_table ");
ResultSet rs = sourceStatement.executeQuery();
rs.setFetchSize(1000); // not needed
ResultSetMetaData meta = rs.getMetaData();
List<String> columns = new ArrayList<>();
for (int i = 1; i <= meta.getColumnCount(); i++)
columns.add(meta.getColumnName(i));
try (PreparedStatement destStatement = destConnection.prepareStatement(
"INSERT INTO dest_table ("
+ columns.stream().collect(Collectors.joining(", "))
+ ") VALUES ("
+ columns.stream().map(c -> "?").collect(Collectors.joining(", "))
+ ")"
)
)
{
int count = 0;
while (rs.next()) {
for (int i = 1; i <= meta.getColumnCount(); i++) {
destStatement.setObject(i, rs.getObject(i));
}
destStatement.addBatch();
count++;
}
destStatement.executeBatch(); // you will see all the rows in dest once this statement is executed
System.out.println("done " + count);
}
There is a mistake in your insert statement chage it to below and try :
String sql = "insert into table_name values ('" + Col1 +"','" + Col2 + "','" + Col3 + "')";
I get an error in this function but I don't know why.
Can you help me?
The error is in the row where I call executeQuery()
public static int numeroElementi(String table) throws SQLException {
// viene reistanziata perché questa è una funziona statica!
String DB_URL = "jdbc:mysql://localhost:3306/kmzero";
Connection connection = DriverManager.getConnection(DB_URL, "root", "root");
String query = "SELECT COUNT(*) AS count FROM ? ";
PreparedStatement pStatement = connection.prepareStatement(query);
pStatement.setString(1, table);
try {
ResultSet resultSet = pStatement.executeQuery();
try {
if (resultSet.next())
return resultSet.getInt("count");
else
return 0;
} finally {
resultSet.close();
}
} finally {
pStatement.close();
}
}
I think you cannot pass the tablename (also columnNames) as a parameter and this is the time when tableName should be concatenated in your string.
String query = "SELECT COUNT(*) AS count FROM " + table;
if your table needs to be escape,
String query = "SELECT COUNT(*) AS count FROM `" + table + "`";