I am trying to use some query result to generate another query and execute the new query but that does not seem to work. The second query is not being executed. Can someone please tell me why? This is that part of the code.
Statment stmt = connnection.createStatement();
Statment stmt2 = connnection.createStatement();
ResultSet r = stmt.executeQuery("Select * from employees");
while (r.next()) {
String Str = "Select name from employees where employeeId = " + (r.getInt(3) + 1);
System.out.println(str);
query = stmt2.executeQuery(str);
System.out.println(query.getString(1));}
The right query seems to be generated, but just won't execute. Is there a reason why this is so. BTW "query" is declared as resultset.
Thanks
you can only have one statement executing at one moment in time against one database connection -- so you can either open another database connection and execute the second statement in the 2nd connection, or iterate through the resultset from first statement and store the employees database id's (e.g. in an array/collection) then close that statement and run the second one, this time retrieving the id's from the array/collection you saved them in.
Related
I am trying to incrementally read SQL Server CDC changes.
In my first interval, I query
Statement statement = connection.createStatement();
String queryString = "SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_mytable(sys.fn_cdc_get_min_lsn('dbo_mytable'), " +
"sys.fn_cdc_get_max_lsn(), 'all') ORDER BY __$seqval";
ResultSet rs = statement.executeQuery(queryString);
Now I know that __$start_lsn is an LSN (Log Sequence Number) in binary(10). Although I don't understand how I can read it as a Java type so that I can include it my next query and how should I create my next query where I will like to specify the min_lsn as the last LSN which I processed.
You can use several options for retrieving the data from the ResultSet
Then for creating a new query, look at using a a PreparedStatement. There are several options for setting the data based on the type that you you pulled out of the initial query.
This question already has an answer here:
Why do I get java.sql.SQLException: ResultSet not open. Operation 'next' not permitted. java derby database?
(1 answer)
Closed 6 years ago.
In connection with another programming project, I am prototyping a JDBC project (with Netbeans, Java, and a Derby database). My program needs to iteratively update all the rows in a database table as follows:
There are three columns in the table: famousName, famousQuote, hashKey.
Originally, the famousQuote column contains a verbatim quote. I want to go down that column using a while loop, get the checksum of the ascii letters, bitwise "AND" with the hashKey value, and then replace the verbatim quote with an "encrypted" value.
As of right now, I try to extract the verbatim famousQuote using a ResultSet object, perform necessary encryption, and then an SQL statement that updates the value. All of this takes place in a while(rs.next()) loop as follows:
(pseudo-code): //all necessary database connections and variable declared here.
String sqlStatement = "Select * FROM mainTable ORDER BY famousName";
ResultSet rs = stmt.executeQuery(sqlStatement);
while(rs.next()){
tempString1 = rs.getString("famousQuote");
tempString2 = rs.getString("hashKey");
tempString3 = EncryptionAlgorithm.EncryptStatement(tempString1, tempString2);
sqlStatement = "UPDATE maintable SET famousQuote=tempString3 WHERE hashKey=tempString2";
(note, there is a bit of pseudo-code regarding the WHERE part,
but I'm sure it's immaterial to the error message I'm getting.)
stmt.executeUpdate(sqlStatement);
}
This seemed like a good idea until the program started throwing errors such as:
ResultSet not open. Operation 'next' not permitted. Verify that autoCommit is off
I later read in the documentation (concerning ResultSet):
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.
Lastly, I guess I could try moving the ResultSet rs declaration inside the while loop, so that it would instantiate a new ResultSet object, but I'm pretty sure this would lose my place in the database (re-updating the first row perpetually).
I'm now at a standstill on how to iterate my way down the table rows, executing my EncryptionAlgorithm on each quote, and then updating the column values in place.
I apologize in advance if my JDBC is a little rusty, but something like this might do the trick:
// 'conn' is your JDBC connection
Statement stmt = conn.createStatement();
PreparedStatement update = conn.prepareStatement(
"UPDATE maintable SET famousQuote=tempString3 WHERE hashKey=tempString2";
String sqlStatement = "Select * FROM mainTable ORDER BY famousName";
ResultSet rs = stmt.executeQuery(sqlStatement);
while(rs.next()){
tempString1 = rs.getString("famousQuote");
tempString2 = rs.getString("hashKey");
tempString3 = EncryptionAlgorithm.EncryptStatement(tempString1, tempString2);
update.setObject(1, tempString3);
update.setObject(2, tempString2);
update.executeUpdate(sqlStatement);
}
I'm using a library that delegates to a JDBC driver for PostgreSQL, and some queries are very complex and require more memory. I don't want to set work_mem to something large for all queries, just this subset. The problem is that executing the following code results in an error:
// pseudo-code for what is happening
String sql = "set work_mem = 102400;";
sql += "SELECT * FROM expensive_query";
ResultSet rs = DatabaseDriver.execute(sql);
When I run this I get an error that:
set work_mem = 102400;
returns no results.
This works in pgAdmin because you can execute multiple queries at once. Is there a better way to do this or do I need to execute arbitrary SQL and then extract the result set I want?
I have no idea what DatabaseDriver does, but with "plain" JDBC you just need to do the following:
Statment stmt = connection.createStatement();
stmt.execute("set work_mem = 102400");
ResultSet rs = stmt.executeQuery("select ...");
Try to do that using Batch Processing
I need to run several queries in a row
Statement st = cnx.createStatement();
ResultSet rs = st.executeQuery( "SELECT [good stuff]");
// do something smart with rs
rs = st.execute( "SELECT [better stuff]");
// do something smarter with rs
rs = st.execute( "SELECT [best stuff]");
// you got it
try{ rs.close();} catch( SQLException ignore){};
try{ st.close();} catch( SQLException ignore){};
Is this a problem that the first two ResultSet are not properly closed or is it implicitely done during garbage collection?
As soon as you execute the 2nd query, the previous ResultSet is automatically closed. And as far as Garbage Collection is concerned, you don't have to worry about that. You can just have a stmt.close() at the end that's all. It will automatically close all the related ResultSet objects.
Take a look at : - ResultSet#close documentation, which says that: -
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.
If you want to test, whether your resultset gets closed or not, you can use a while loop to iterate over the result set and inside the while loop, create another query and assign it to same result set. You will see that an Exception will be thrown..
ResultSet res = stmt.executeQuery("SELECT * FROM sometable");
while (res.next()) {
res.getString(1);
// Closes the previous `ResultSet`
res = stmt.executeQuery("SELECT * FROM othertable");
}
So, in the above code, on the 2nd iteration, you will get an Exception: - Cannot perform operation after ResultSet is closed
I don't know what's your problem, but if you have some problems to run this code, you can try to close connection and open other to make the second query. Some database products, like SQLite, only admit one open connection. If you have any problem with database access, you should try that.
I am taking domains from a text file and passing it to a query one by one.
for first time the query is executing fine .. but when it takes the second domain and passing it to query getting error "ORA-00933: SQL command not properly ended"
Below is the code
sql.append("select person_org_id,profile_type_id as NEXUS, profile_option_id,profile_option_value from TABLE1 ");
sql.append(" where profile_type_id=1 and person_org_id in (select person_org_id from TABLE2 where ");
sql.append(" account_id in (select account_id from TABLE3 where prod_id=10001 and prod_inst_name = ?)) ");
ps = con.prepareStatement(sql.toString());
System.out.println("----------checkpoint -----------");
ps.setString(1,domain_name);
System.out.println("----------checkpoint 4-----------");
rs= ps.executeQuery();
System.out.println("----------checkpoint 5-----------");
If you have this code in a loop, and you do not clear the StringBuilder or use a new one, then the second time around, you will have the SQL statement twice and that would explain the error.
Why use a StringBuilder at all if a simple String would do? There is no variation in the SQL statement at all. Of course, this may have been a simplified example.
Also, if you do this in a loop, and the SQL is indeed the exact same one every time, you could just prepare the statement once, and execute it repeatedly in the loop. That is kind of what prepared statements are for.