the value of Resultset while getting now rows form database - java

i want to know that while firing the select query from database in java(JDBC).suppose that
the execute(Query) return no rows then what will be thae value of Resultset object??? is it null or can be other ??? Reply please
Statement statement = connection.createStatement();
ResultSet result = statement.executeQuery("select * from people");

Check this Execute Query , it states
a ResultSet object that contains the data produced by the given query; never null
So the result set is empty not null

See Javadocs for Statement Interface it is clearly mentioned that executeQuery never returns null. If there are no rows to fetch then it will return an empty resultset.

Related

How to insert a ResultSet into a new MYSQL table? [duplicate]

This question already has an answer here:
java.sql.SQLException: Operation not allowed after ResultSet closed MySQL Java [duplicate]
(1 answer)
Closed 6 years ago.
I want to insert the result of execution of a MYSQL query into another MYSQL table. Following is the code snippet:
rs1 = st.executeQuery(query1);
while(rs1.next()){
insertData(species,rs1,"try");
}
The resultset rs1 contains n number of rows returned as a result of execution of query1. I am trying to insert all rows in rs1 into another table. Insertion operation is carried out in the function insertData() as follows:
public void insertData(String species, ResultSet rs, String table)throws Exception{
String q = "Insert into "+table+" values("+rs.getFloat("sl")+","+rs.getFloat("sw")+","+rs.getFloat("pl")+","+rs.getFloat("pw")+",'"+rs.getString("classification")+"')";
int x = st.executeUpdate(q);
if( x == 0)
System.out.println("Error inserting data");
}
After I run the code, I get the following exception:
Operation not allowed after ResultSet closed
As far as I know, rs1.next() points the cursor to the first row in the first iteration.
Please correct me if I am missing something fundamental here.
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.
Quoted from Statement Java doc
You use the same Statement st object execute different queries twice.
rs1 = st.executeQuery(query1); // executed before while loop
int x = st.executeUpdate(q); // executed in while loop
When you execute st.executeUpdate(q); in your insertData() method, ResultSet rs1 is closed. You need to create a new Statement and execute the second query.

Result set stored in hashMap giving zero row count

I have two methods in my class, First I am calling method dbExecuteStatement(), which execute the sql query. After execution of sql query, I get a ResultSet object. I am saving this ResultSet object in a static hashMap, so that on my next method call fetchResults(), I can use the existing result set to retrieve the results. Reason for saving the ResultSet object in a map is ,in fetchResults() method request parameter, I will get the max fetch row size, and on basis of that value I will be iterating the result set. Both of this methods are supposed to be called individual from the client side.
Now the problem, I am facing is that, When I am iterating the ResultSet object in fetchResults() method, I am getting the row count zero. If I fetch the same ResultSet from a hashMap in dbExecuteStatement(), I get the actual row count i.e 5 in my case. I checked the ResultSet object that I have put in the hash map in fetchResults() method and dbExecuteStatement(), it is the same object. But If get the ResultSetMetaData object in fetchResults() method and dbExecuteStatement(), they are coming different. Can someone help me in understanding the cause, Why I am getting the result count zero.
Below is the code:
public class HiveDao1 {
private static Map<Object,Map<Object,Object>> databaseConnectionDetails
= new HashMap<Object,Map<Object,Object>>();
//This method will execute the sql query and will save the ResultSet obj in a hashmap for later use
public void dbExecuteStatement(DbExecuteStatementReq dbExecuteStatementReq){
//I already have a connection object saved in map
String uniqueIdForConnectionObject = dbExecuteStatementReq.getDbUniqueConnectionHandlerId();
Map<Object,Object> dbObject = databaseConnectionDetails.get(uniqueIdForConnectionObject);
Connection connection = (Connection) dbObject.get(DatabaseConstants.CONNECTION);
try {
Statement stmt = connection.createStatement() ;
// Execute the query
ResultSet resultSet = stmt.executeQuery(dbExecuteStatementReq.getStatement().trim()) ;
//save the result set for further use, Result set will be used in fetchResult() call
dbObject.put(DatabaseConstants.RESULTSET, resultSet);
/*
* Now below is the debugging code,which I put to compare the result set
* iteration dbExecuteStatement() and fetchResults method
*/
ResultSet rs = (ResultSet) dbObject.get(DatabaseConstants.RESULTSET);
ResultSetMetaData md = (ResultSetMetaData) dbObject.get(DatabaseConstants.RESULTSETMETADATA);
System.out.println("==ResultSet fethced in dbExecuteStatement=="+rs);
System.out.println("==ResultSet metadata fetched in dbExecuteStatement ==="+rs.getMetaData());
int count = 0;
while (rs.next()) {
++count;
}
if (count == 0) {
System.out.println("No records found");
}
System.out.println("No of rows found from result set in dbExecuteStatement is "+count);
} catch (SQLException e) {
e.printStackTrace();
}
}
/*
* This method fetch the result set object from hashMap
* and iterate it on the basis of fetch size received in req parameter
*/
public void fetchResults(FetchResultsReq fetchResultsReq){
String uniqueIdForConnectionObject = fetchResultsReq.getDbUniqueConnectionHandlerId();
Map<Object,Object> dbObject = databaseConnectionDetails.get(uniqueIdForConnectionObject);
try {
//Fetch the ResultSet object that was saved by dbExecuteStatement()
ResultSet rs = (ResultSet) dbObject.get(DatabaseConstants.RESULTSET);
ResultSetMetaData md = (ResultSetMetaData) dbObject.get(DatabaseConstants.RESULTSETMETADATA);
System.out.println("ResultSet fethced in fetchResults at server side dao layer======"+rs);
System.out.println("ResultSet metadata fetched in fetchResults at server side dao layer======"+md);
int count = 0;
while (rs.next()) {
++count;
}
if (count == 0) {
System.out.println("No records found");
}
//Here the row count is not same as row count in dbExecuteStatement()
System.out.println("No of rows found from result set in fetchResults is "+count);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Expanding on my comment (And #Glenn's):
Using a ResultSet more than once
When you write debug code that iterates a ResultSet, the cursor moves to the end of the results. Of course, if you then call the same object and use next(), it will still be at the end, so you won't get any more records.
If you really need to read from the same ResultSet more than once, you need to execute the query such that it returns a scrollable ResultSet. You do this when you create the statement:
Statement stmt = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY );
The default statement created by connection.createStatement() without parameters returns a result set of type ResultSet.TYPE_FORWARD_ONLY, and that ResultSet object can only be read once.
If your result set type is scroll insensitive or scroll sensitive, you can use a statement like rs.first() to reset the cursor and then you can fetch the records again.
Keeping the statement in scope
#Glenn's comment is extremely important. The way your program works right now, it may work fine throughout the testing phase, and then suddenly in production, you'll sometimes have zero records in your ResultSet, and the error will be reproducible only occasionally - a debug nightmare.
If the Statement object that produces the ResultSet is closed, the ResultSet itself is also closed. Since you are not closing your Statement object yourself, this will be done when the Statement object is finalized.
The stmt variable is local, and it's the only reference to that Statement that we know of. Therefore, it will be claimed by the garbage collector. However, objects that have a finalizer are relegated to a finalization queue, and there is no way of knowing when the finalizer will be called, and no way to control it. Once it happens, the ResultSet becomes closed out of your control.
So be sure to keep a reference to the statement object alongside your ResultSet. And make sure you close it properly yourself once you are done with the ResultSet and will not be using it anymore. And after you close it remember to remove the reference you have kept - both for the statement and the result set - to avoid memory leaks. Closing is important, and relying on finalizers is a bad strategy. If you don't close it yourself, you might run out of cursors at some point in your database (depending on the DBMS and its configuration).

Move rs to method causes Exception

I have some duplicated following code
rs = prepStmt.executeQuery();
rs.next();
I want to move it to a method so that I can reuse the code. The method is like:
public static void point(ResultSet rs, PreparedStatement prepStmt){
rs = prepStmt.executeQuery();
result = rs.next();
}
Then I want to get a column value, like, String gender = rs.getString("gender");
And I get the following exception:
java.sql.SQLException: Invalid column name gender. The error does not show up when I did't
encapsulate the logic in the method. So the column name is correct.
Any ideas? Thanks!
You seem to be assuming that the change to the rs parameter will be propagated to the calling code. It won't. Everything in Java is passed by value - including references. Instead, you should probably do something like:
public static ResultSet point(PreparedStatement prepStmt) {
ResultSet rs = prepStmt.executeQuery();
result = rs.next();
return rs;
}
You'd then call it as:
ResultSet rs = point(prepStmt);
(It's not clear what result is either, or whether it's really worth declaring a whole extra method just to avoid calling rs.next() directly... especially when it means the result of rs.next() is somewhat obscured...)

rs.next returns only one result in java

I am attempting to run following code :
ResultSet rs=DatabaseConnection.executeQuery("Select * from csr where c_No="+this.c_No);
if(rs.next()){
ob_id=rs.getInt("ID");
}
ResultSet rs1=DatabaseConnection.executeQuery("Select * from cs_details");
if(rs1.next()){
cs_id=rs1.getInt("cs_Id");
DatabaseConnection.executeUpdate("Insert into transact (ob_ID, cs_ID, quant) values("+this.ob_id+", "+this.cs_id+", 0)");
}
In this code, ob_id returns only one value from database which is true. But second query returns multiple rows from which I need to keep only a single column value i.e. cs_id (every time). But while executing this code, it takes only first cs_id value in database & insert only one record in "transact" table. I need to insert all records with respective values of cs_id. How to solve this problem???
Instead of
if (rs1.next()) {
cs_id=rs1.getInt("cs_Id");
DatabaseConnection.executeUpdate("Insert into transact (ob_ID, cs_ID, quant) values("+this.ob_id+", "+this.cs_id+", 0)");
}
do
while (rs1.next()) {
cs_id=rs1.getInt("cs_Id");
DatabaseConnection.executeUpdate("Insert into transact (ob_ID, cs_ID, quant) values("+this.ob_id+", "+this.cs_id+", 0)");
}
to loop through all records in the ResultSet.

Why is While (rs.next()) statement ending after 1st iteration?

I am using a SELECT statement to get data from a table and then insert it into another table. However the line "stmt.executeQuery(query);" is inserting the first line from the table then exits. When I comment this line out, the while loop loops through all the lines printing them out. The stacktrace isn't showing any errors. Why is this happening?
try{
String query = "SELECT * FROM "+schema_name+"."+table;
rs = stmt.executeQuery(query);
while (rs.next()) {
String bundle = rs.getString("BUNDLE");
String project_cd = rs.getString("PROJECT_CD");
String dropper = rs.getString("DROPPER");
String week = rs.getString("WEEK");
String drop_dt = rs.getString("DROP_DT").replace(" 00:00:00.0","");
query = "INSERT INTO INDUCTION_INFO (BUNDLE, PROJECT_CD, DROPPER, WEEK, DROP_DT) "
+ "VALUES ("
+ bundle+","
+ "'"+project_cd+"',"
+ dropper+","
+ week+","
+ "to_date('"+drop_dt+"','YYYY-MM-DD'))";
System.out.println(query);
stmt.executeQuery(query);
}
}catch(Exception e){
e.printStackTrace();
}
You are re-using the Statement that was used to produce rs on the last line of your loop.
This will close the ResultSet rs. As stated in the documentation:
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.
You need to use a second Statement object to execute the INSERT statements.
Statement objects can only do one thing at a time, so when you execute that INSERT, you invalidate the ResultSet which it generated. You'll need to create a second Statement object to perform the INSERT.
From the Statement documentation: "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."
if you use the same statement, it will invalidate the previous result set. You should use a different statement to perform updates/inserts.
This is from the Java docs of interface Statement:
By default, only one ResultSet object per Statement object can be open
at the same time.
So you better use a second Statement or even better a PreparedStatement.
And to execute an INSERT SQL statement you should use executeUpdate() instead of executeQuery().

Categories

Resources