Operation not allowed after ResultSet Closed error Netbeans MySQL Connectivity - java

I am creating a program to rename databases in mysql.
I have succeeded in everything and it successfully happens. But in the end of my script, its shows an error/exception saying "Operation not allowed after ResultSet closed". I really have no idea why this error appears even after researching about this error.
Although the full operation is successfully completed and the database is renamed.
Here is my code->
String x = (String) jComboBox1.getSelectedItem(); //jComboBox1 contains the name of current database selected
String z = JOptionPane.showInputDialog("Please enter new name for Database"); //Where user enters the name for new database.
new CustComm().setVisible(false); //Frame that carries the names of tables.
try{
Class.forName("java.sql.DriverManager");
Connection con = (Connection)
DriverManager.getConnection("jdbc:mysql://localhost:"+GlobalParams.portvar+"/",""+k,""+j);
Statement stmnt = (Statement) con.createStatement();
String query = "use "+x;
stmnt.executeQuery(query);
String query2 = "show tables";
ResultSet rs = stmnt.executeQuery(query2);
while (rs.next()){
String dname = rs.getString("Tables_in_"+x);
if(CustComm.jTextArea1.getText().equals("")){
CustComm.jTextArea1.setText(CustComm.jTextArea1.getText()+dname);
}
else{
CustComm.jTextArea1.setText(CustComm.jTextArea1.getText()+"\n"+dname);
}
String y = CustComm.jTextArea1.getText();
Scanner scanner = new Scanner(y);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String query3 = "Create database "+z;
stmnt.executeUpdate(query3);
//alter table my_old_db.mytable rename my_new_db.mytable
String query4 = "RENAME TABLE "+x+"."+line+" TO "+z+"."+line;
stmnt.executeUpdate(query4);
String query5 = "drop database "+x;
stmnt.executeUpdate(query5);
}}}
catch(Exception e){
JOptionPane.showMessageDialog(this,e.getMessage());
}
Please help.

You shouldn't execute new queries on statement Statement stmnt = (Statement) con.createStatement(); while you use ResultSet from it, because this will close your ResultSet.
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.
You should create 2 different statements: first for query2 and second for queries 3-5.
Also it's better to use PreparedStatement. You can read about the difference here.

Do you have to do this work via code? Have you looked into tools like Liquibase?

Related

i am trying to get id from table name data base to stor in variable so i can use in another table it give sql syntax error

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+"%'");

How to execute MySQL query, "show tables;" inside a Java Program..?

I am a newbie to Java and MySQL. Please pardon me if my question seems silly, I want to know the answer...
I have gone through many articles and questions asked in forums, but I didn't see a relevant answer for my question...
That is, I have made a switch statement in Java and I want to show the list of available tables in a database if I press 1( that is go into the case 1 and execute a query "show tables;" )
In MySQL Console, it is easy to check for available tables using the same query. But I want to know whether "show tables;" query or similar queries can be executed inside a Java Program...
Here's a sample snippet of my code,
Connection con=null;
String url = "jdbc:mysql://localhost:3306/giftson";
String dbName = "giftson";
String userName = "root";
String password = "password";
con=DriverManager.getConnection(url,userName,password);
Statement st=con.createStatement();
//String query;
Statement st=con.createStatement();
System.out.println("\tDatabase Connection for Various Operations");
System.out.println("\n1. Show list of tables\n2. Show contents of Table\n3. Create New Table\n4. Insert into table\n5. Update Table\n6. Delete From Table\n7. Exit\n");
System.out.println("Enter your option Number ");
DataInputStream dis=new DataInputStream(System.in);
int ch=Integer.parseInt(dis.readLine());
switch(ch)
{
case 1:
System.out.println(" You have selected to Show list of available tables");
//ResultSet rs=st.executeQuery("Show tables");
//while(rs.next())
//{
// System.out.println("List of Tables\n" +rs.getString("?????"));
//}
break;
}
from the above piece of code,
If I execute the query in ResultSet, How do I print the values inside the while loop..?
In rs.getString(); we can only pass either the column index or the column label as argument, but how do I get the list of tables...
what do I enter in place of "?????" inside print statement...?
please do help me, keeping in mind that you are explaining for a beginner...
Thanks in advance...!
We can use the console commands using,
DatabaseMetaData meta=getMetaData();
In the below code, it is shown that there are many ways (but I came to know two ways) of getting the list of tables
DatabaseMetaData meta = con.getMetaData();
ResultSet rs1 = meta.getTables(null, null, null,new String[] {"TABLE"});
ResultSet rs2 = meta.getTables(null, null,"%", null);
System.out.println("One way of Listing Tables");
while (rs1.next())
{
System.out.println(rs1.getString("TABLE_NAME"));
}
System.out.println("Another way of Listing Tables");
while(rs2.next())
{
System.out.println(rs2.getString(3));
}
A small example would be
String tableNamePattern = "%_Assessment_" + session + "_" + year;
DatabaseMetaData databaseMetaData = conn.getMetaData();
ResultSet rs = databaseMetaData.getTables(null, null, tableNamePattern,
null);
while(rs.next()) {
String tableName = rs.getString("TABLE_NAME");
...
}
Check the source

SQL command from eclipse using JDBC

I have been searching and trying different stuff for awhile, but have not found an answer. I'm trying to make a connection to sql using JDBC from eclipse. I am having trouble when I need to select a string in the database. If I use:
Select name from data where title = 'mr';
That works with terminal/command line but when I try to use eclipse where I use
statement sp = connection.createstatement();
resultset rs = sp.executequery("select name from data where title = '" + "mr" + "'");
It does not give me anything while the terminal input does. What did I do wrong in the eclipse? Thanks
Heres a part of the code. Sorry, its a bit messy, been trying different things.
private boolean loginChecker(String cid, String password) throws SQLException{
boolean check = false;
PreparedStatement pstatment = null;
Statement stmt = null;
//String query = "SELECT 'cat' FROM customer";
String query = "select '"+cid+"' from customer where password = '"+password+"'";
try {
System.out.println("in try......");
//stmt = con.createStatement();
//ResultSet rs = stmt.executeQuery(query);
PreparedStatement prepStmt = con.prepareStatement(query);
ResultSet rs = prepStmt.executeQuery();
//System.out.print(rs.getString("cid"));
while(rs.next()){
check = true;
System.out.print(rs.getString("cid"));
}
} catch (SQLException e ) {
e.printStackTrace();
} finally {
if (stmt != null) {
//stmt.close();
}
}
return check;
}
Second try on a simpler query:
public List<Object> showTable() {
List<Object> result = new ArrayList<Object>();
String name = "bob";
try
{
PreparedStatement preStatement = con.prepareStatement("select total from test where name = ?");
preStatement.setString(1, name);
ResultSet rs1 = preStatement.executeQuery();
while(rs1.next()){
System.out.println("there");
System.out.println(rs1.getInt("total"));
}
}
catch (SQLException ex)
{
System.out.print("Message: " + ex.getMessage());
}
return result;
}
Remove the quotes around the column name.
String query = "select "+cid+" from customer where password = '"+password+"'";
You've not mentioned which database you're working with but many databases like Oracle change the column case to upper case unless they're quoted. So, you only quote table columns if that's how you had created them. For example, if you had created a table like
CREATE TABLE some_table ( 'DoNotChangeToUpperCase' VARCHAR2 );
Then you would have to select the column with quotes as well
SELECT 'DoNotChangeToUpperCase' FROM some_table
But, if you didn't create the table using quotes you shouldn't be using them with your SELECTs either.
Make sure you are not closing the ResultSet before you are trying to use it. This can happen when you return a ResultSet and try to use it elsewhere. If you want to return the data like this, use CachedRowSet:
CachedRowSet crs = new CachedRowSetImpl();
crs.populate(ResultSet);
CachedRowSet is "special in that it can operate without being connected to its data source, that is, it is a disconnected RowSet object"
Edit: Saw you posted code so I thought I add some thoughts. If that is your ACTUAL code than the reason you are not getting anything is because the query is probably not returning anything.
String query = "select '"+cid+"' from customer where password = '"+password+"'";
This is wrong, for two reasons. 1) If you are using prepared statements you should replace all input with '?' so it should look like the following:
String query = "select name from customer where password = ?";
Then:
PreparedStatement prepStmt = con.prepareStatement(query);
prepStmt.setString(1, password);
ResultSet rs = prepStmt.executeQuery();
2)
System.out.print(rs.getString("cid"));
Here are are trying to get the column named "cid", when it should be the name stored in cid. You should actually never be letting the user decide what columns to get, this should be hardcoded in.

JAVA: get cell from table of mysql

I get a parameter is called 'id' in my function and want to print the cell of the name of this id row.
for example:
this is my table:
id name email
1 alon alon#gmail.com
I send to my function: func(1), so I want it to print 'alon'.
this is what I tried:
static final String url = "jdbc:mysql://localhost:3306/database_alon";
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, "root", "Admin");
String query_txt = "SELECT * FROM authors WHERE id = " + id;
Statement ps2 = con.createStatement();
ResultSet my_rs = ps2.executeQuery(query_txt);
System.out.println(my_rs.getString("name"));
con.close;
Everything is fine, but just one problem. You need to move your ResultSet cursor to the first row before fetching any values: -
Use: -
ResultSet my_rs = ps2.executeQuery(query_txt);
while (my_rs.next()) {
System.out.println(my_rs.getString("name"));
}
As a side note, consider using PreparedStatement to avoid getting attacked by SQL Injection.
Here's how you use it: -
PreparedStatement ps2 = con.prepareStatement("SELECT * FROM authors WHERE id = ?");
ps2.setInt(1, id);
ResultSet my_rs = ps2.executeQuery();
while (my_rs.next()) {
System.out.println(my_rs.getString("name"));
}
You need to use ResultSet.next() to navigate into the returned data:
if (my_rs.next()) {
System.out.println(my_rs.getString("name"));
}
Call my_rs.next(), which will move the ResultSet cursor onto the first row (which you are extracting data out of).
If this is a real application, use PreparedStatements instead of generic Statements. This is an extremely important matter of security if you plan on using user input in SQL queries.

Getting java.sql.SQLException: Operation not allowed after ResultSet closed

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.

Categories