It is possible to execute the following PreparedStatement:
PreparedStatement s = conn.prepareStatement("select 'a' as a; select 'b' as b");
s.execute();
That is, the statement can contain more than one SQL statement.
However, if I call s.getResultSet(), it only takes the first query into consideration (the one returning "a"). How can I get the last ResultSet from this statement?
You may use a getMoreResults()which moves to this Statement object's next result,and implicitly closes any current ResultSet object(s) obtained with the method getResultSet and then again calling getResultSet().
Related
String name;
int sum;
myRs = myStmt.executeQuery("SELECT DISTINCT person FROM Todo_tbl");
while (myRs.next()) {
name = myRs.getString("person");
System.out.println(name);
sum = 0;
ResultSet myRs2 = myStmt.executeQuery("SELECT duration FROM Todo_tbl WHERE person ='" + name + "' ");
while (myRs2.next()) {
sum += (int) myRs2.getInt("duration");
JList<Integer> list2 = new JList<>();
}
dfduration.addElement(sum);
}
That is the code I use, the problem is that the loop only goes through one name and closes after. I am not sure why, the code is supposed to go through all the names in the database and sum the values assigned to the same name.
I will be so grateful for any help!
You are attempting to use two ResultSets generated by the same Statement in interleaving fashion. This will not work. As the API docs for java.sql.Statement put it:
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 current ResultSet object of the statement
if an open one exists.
Thus, as soon as you perform the myStmt.executeQuery() inside the inner loop, the ResultSet to which myRs refers is closed. The next call to myRs.next() therefore returns false, and no further loop iterations are performed.
I suggest a different query:
SELECT person, duration FROM Todo_tbl ORDER BY person
Then use a single loop over the results. Aside from not requiring multiple Statements, it would use only one query, which is much more efficient.
Alternatively, leave out the ORDER BY clause, and perform the grouping by person on the Java side, with the help of a Map.
On the other hand, if all you want to do is get the sum of all of each person's durations (the code presented does nothing else, but maybe you want the individual points for some purpose not reflected in the question) then the best alternative would probably be to make the database do the work:
SELECT person, SUM(duration) as total_duration FROM Todo_tbl GROUP BY person
Any way around, details of how to write the appropriate loop for handling those results are left as an exercise.
Statement stmt=conn.createStatement(); //1
Statement stmt2=conn.createStatement(); //2
ResultSet resultSet1=stmt.executeQuery("-----"); //3
while(resultSet1.next()) { //4
ResultSet resultSet2 = stmt.executeQuery("-----"); //5
}
Will Line Number 5 cause any changes in resultSet1 (declared in line 3 )....As per my observation, resultSet1 had been changed after the execution on line 5.
Please explain whether my observation is right or wrong.
From Statement javadoc:
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.
I am trying to implement a task in java using JDBC like Stored Procedure in SQL.
In SQL, when we write cursor, first we execute select query and then fetching the records we perform some actions.
Likely I have fired a select query in Hive.
sql="SELECT a,c,b FROM tbl_name";
res=stmt.executeQuery(); -----------> CONTAINS 30 RECORDS
while(res.next())
{
sql="INSERT INTO table .....";
rs1=stmt.executeQuery();
sql="SELECT d,e,f FROM table .....";
rs1=stmt.executeQuery();
like wise many queries are there.....
.
.
.
..
}
As my select query contains 30 records but when I execute it my while(res.next()) execute only once.
But instead of queries I just try to display field to check whether it is fetching or not
then it is working fine..
(while loop contains only System.out.println statements)
sql="SELECT * FROM tbl_name";
res=stmt.executeQuery(sql);
while(res.next())
{
S.O.P.("fields : "+res.getString(0));
}
(I think that when the resultset is getting traversed and if in between queries are there then queries get the executed but at the same time loop also get executes and after some time when queries execution get finishes by that while loop of resultset also get finishes and hence it get executes for once. I am not sure about it.)
Why it is happening I am not getting. Is anything I am doing wrong?
Each Statement can only have one open ResultSet at a time. From the 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.
The calls to executeQuery inside your loop will implicitly close the outer ResultSet, so that's why you only see one row.
I would restructure your flow. Primarily, don't try and reuse the same Statement object to execute a new query. When I try that using the PostgreSQL driver, for example, I readily get an exception, "This ResultSet is closed."
Instead, rewrite it to something like this:
Connection conn = DriverManager.getConnection(...);
Statement outerStatement = conn.createStatement();
ResultSet outerResultSet = outerStatement.executeQuery("...");
while (outerResultSet.next()) {
Statement innerStatement = conn.createStatement();
ResultSet innerResultSet = innerStatement.executeQuery("...");
while (innerResultSet.next()) {
// ...
}
innerResultSet.close();
innerStatement.close();
}
outerResultSet.close();
outerStatement.close();
conn.close();
Of course, surround with try-catch-finally as needed.
It doesn't happen like that, You can try until your query gets executed loop will wait.
ideally you can only have one statement executing at one moment in time against one database connection so you can either create and execute the second statement, or iterate through the resultset from first statement and store the data in collection (e.g. in an arraylist of hashmap) then close that statement and run the second one, this time retrieving the id's from the collection you saved them in.
I am using odbc to connect mysql database in Java
I write a function "ExecuteQuery", it takes a string parameter as sql statement and returns its resultset. However, when should I close the statement object?
If I close it in function ExecuteQuery, the returned resultset will be closed as well.
If I don't close it, memory leak occurs as I do not have the reference of statement object in caller. Thank you
You're taking wrong approach. If you really need such function (which is doubtful), make it accept a Statement as a parameter and make a separate function to create and set up that statement. Then you may wrap your function and ResultSet work in a try..finally block and close the statement in finally.
E.g.
Statement statement = getStatement();
try {
ResultSet rs = executeQuery(statement, query);
...
} finally {
statement.close();
}
However, if you're facing such problems, you may want to re-consider your architecture. Take a look at Hibernate, for example.
Is recommended to create just one Statement object and execute multiple executeUpdate() on it?
// Vantages/drawbacks of this solution?
conn.setAutocommit(false);
Statement stmt = conn.createStatement();
stmt.executeUpdate('[ANY_INSERT_SQL]');
stmt.executeUpdate('[ANY_INSERT_SQL]');
stmt.executeUpdate('[ANY_INSERT_SQL]');
conn.commit();
Or is better one Statement object for each executeUpdate:
// Vantages/drawbacks of this solution?
conn.setAutocommit(false);
Statement stmt1 = conn.createStatement();
stmt1.executeUpdate('[ANY_INSERT_SQL]');
Statement stmt2 = conn.createStatement();
stmt2.executeUpdate('[ANY_INSERT_SQL]');
Statement stmt3 = conn.createStatement();
stmt3.executeUpdate('[ANY_INSERT_SQL]');
conn.commit();
Thanks in advance.
PS: I know PreparedStatement class and I use it often, but my doubt is about Statement usage.
It doesn't matter, just make sure you close all statement objects.
Based on the javadoc, A statement can have only one associated ResultSet object.
The object used for executing a static
SQL statement and returning the
results it produces.
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.
http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Statement.html
If you need to process multiple results sets at the same time, perhaps, more statements make sense.
Probably more often than not, you only need to use one.
Performance-wise, probably better as it keeps fewer resources active.