This is java program for SQL statement. I have two queries. Result of the first query is required for second query.
How do I call it in second query?
These results are values for xml tags.
I need to get first query result for this tag
child1.setAttributeNS(xlink,"xlink:type","");
but this is located in 2nd query and if i try to merge those 2 query I get eror resultset closed.
while(rs1.next()){
int i=0,j=0 ,locid,supid;
int lc[]=new int[100];
int sp[]=new int[100];
lc[i] = rs1.getInt(2);
sp[j] = rs1.getInt(1);
lcid=lc[i++];*/
for(i=0;i<loc[i];i++){
for(j=0;j<sup[j];j++){
lcid=lc[i]; spid=sp[j];
System.out.print(spid +" ");
System.out.println(lcid);
String s = (lc[i]==1 ? "simple" : (lc[i]>1 ? "extended" : null));
System.out.println(s); }}}
String querystring=
" ";
rs = stmt.executeQuery(querystring );
while(rs.next()){
Element child1 = doc.createElement("slink");
/
Element element = doc.createElement("loc");
You need to create a brand new and separate Statement for the second ResultSet. Everytime you get a new ResultSet out of a single Statement, every previously opened one will namely be closed.
Replace
rs = stmt.executeQuery(querystring );
by
Statement stmt2 = connection.createStatement();
rs = stmt2.executeQuery(querystring);
Don't forget to add stmt2.close() to the finally block.
Unrelated to the concrete problem, have you considered just JOINing the both queries and using Javabeans to represent the model? This way you end up with a single query and more self-documenting code.
Related
Hello this looks like simple but I am having issues here.
Firstly I am using Statement#executeBatch for executing many UPDATE statements. Each update statements have String value to be updated. These String have " ' " single quote. I have tried adding one more single quote in front of it as per Oracle doc as well adding '\\\' in front of single quote. With the first one, my query gets stuck and does not come out even after 10 minutes. With second one I get 'batching: ORA-00927: missing equal sign' error.
What is the correct approach?
Note:- I cannot use PreparedStatement to make use of JDBC parameters.
Please help.
You may use the q-quoted string eg q'['''''''']'
This give a following example
Statement stmt = con.createStatement();
stmt.addBatch("update tst set txt = q'['''''''']' where id = 1");
stmt.addBatch("update tst set txt = q'['''''''']' where id = 2");
stmt.addBatch("update tst set txt = q'['''''''']' where id = 3");
stmt.addBatch("update tst set txt = q'['''''''']' where id = 4");
stmt.addBatch("update tst set txt = q'['''''''']' where id = 5");
// submit a batch of update commands for execution
int[] updateCounts = stmt.executeBatch();
But the correct way is to use the prepared statement
PreparedStatement stmt = con.prepareStatement("update tst set txt = ? where id = ?");
5.times { i ->
stmt.setString(1, "''''''''");
stmt.setInt(2, i+1);
stmt.addBatch();
}
// submit a batch of update commands for execution
int[] updateCounts = stmt.executeBatch();
I have an assignment where I need to update records using a PreparedStatement. Once the record have been updated as we know update query return count, i.e., number of row affected.
However, instead of the count I want the rows that were affected by update query in response, or at least a list of id values for the rows that were affected.
This my update query.
UPDATE User_Information uInfo SET address = uInfo.contact_number || uInfo.address where uInfo.user_id between ? AND ?;
Normally it will return count of row affected but in my case query should return the ids of row or all the row affected.
I have used the returning function of PostgreSQL it is working but is not useful for me in that case.
i have used returning function of PostgreSQL but is not useful for me
It should be. Perhaps you were just using it wrong. This code works for me:
sql = "UPDATE table1 SET customer = customer || 'X' WHERE customer LIKE 'ba%' RETURNING id";
try (PreparedStatement s = conn.prepareStatement(sql)) {
s.execute(); // perform the UPDATE
try (ResultSet rs = s.getResultSet()) {
// loop through rows from the RETURNING clause
while (rs.next()) {
System.out.println(rs.getInt("id")); // print the "id" value of the updated row
}
}
}
The documentation indicates that we can also use RETURNING * if we want the ResultSet to include the entire updated row.
Update:
As #CraigRinger suggests in his comment, the PostgreSQL JDBC driver does actually support .getGeneratedKeys() for UPDATE statements too, so this code worked for me as well:
sql = "UPDATE table1 SET customer = customer || 'X' WHERE customer LIKE 'ba%'";
try (PreparedStatement s = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
s.execute(); // perform the UPDATE
try (ResultSet rs = s.getGeneratedKeys()) {
while (rs.next()) {
System.out.println(rs.getInt(1)); // print the "id" value of the updated row
}
}
}
Thanks, Craig!
You might be able to use JDBC's support for getting generated keys. See the Connection.prepareStatement(String sql, int[] columnIndexes) API method, then use Statement.getGeneratedKeys() to access the results.
The spec says "the driver will ignore the array if the SQL statement is not an INSERT statement" but I think PostgreSQL's JDBC driver will actually honour your request with other statement types too.
e.g.
PreparedStatement s = conn.prepareStatement(sql, new String[] {'id'})
s.executeUpdate();
ResultSet rs = s.getGeneratedKeys();
Otherwise, use RETURNING, as Gord Thompson describes.
There are two way of doing it
1. by passing an array of column name or index of column prepareStatement
i.e conn.prepareStatement(sql, new String[] {'id','uname'})
and
2. by using Statement.RETURN_GENERATED_KEYS in prepareStatement.
My code is for this i.e as per my requirement i have developed my code you can have a look for better idea.
private static final String UPDATE_USER_QUERY= "UPDATE User_Information uInfo SET address = uInfo.contact_number || uInfo.address where uInfo.user_id between ? AND ?;";
//pst = connection.prepareStatement(UPDATE_USER_QUERY,columnNames);
pst = connection.prepareStatement(UPDATE_USER_QUERY,Statement.RETURN_GENERATED_KEYS);
ResultSet rst = pst.getGeneratedKeys();
List<UserInformation> userInformationList = new ArrayList<UserInformation>();
UserInformation userInformation;
while (rst.next()){
userInformation = new UserInformation();
userInformation.setUserId(rst.getLong("user_id"));
userInformation.setUserName(rst.getString("user_name"));
userInformation.setUserLName(rst.getString("user_lName"));
userInformation.setAddress(rst.getString("address"));
userInformation.setContactNumber(rst.getLong("contact_number"));
userInformationList.add(userInformation);
}
That think i need to achieve in this case.
Hope so this will help you a lot.
I write a little program to admin my video collection.
/*
insert new data set into the table
*/
int next = 0;
rs = st.executeQuery("Select max(category_id) from category;");
if (rs.next()) {
next = rs.getInt(1) + 1;
System.out.println(next);
}
String query = "INSERT INTO category VALUES (" + next + ", 'Mystics', now());";
rs = st.executeQuery(query);
//on this place is the exception thrown
// this will not execute anymore
rs = st.executeQuery("DELETE FROM category WHERE name = 'Mystics';");
The program can select on tables, make joins but insert make trouble.
I try to insert some new data in my table (see Java-code). After the second test the output show me that the data was inserted. But after Insert was an exception thrown.
1 & 2 are the tests from yesterday and today. (3) was inserted but not selected yet.
1 Mystics 2015-07-05
2 Mystics 2015-07-06
3
org.postgresql.util.PSQLException: query produced no result.
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:287)
at postgre_java.Zetcode.main(Zetcode.java:55)
do you have some advises for me?
Do not manipulate data with read statements!
If you want to insert, update, delete data in db use
Statement stmt = conn.createStatement();
stmt.executeUpdate(SQL);
executeQuery returns resultset, but all that INSERT, UPDATE, DELETE can return is number of affected rows and that is what executeUpdate is returning.
And never, never, never*100 use string concatenation in SQL use Prepared statements!
In Java, you use executeQuery for a SELECT statement or some other statement which returns something. If you want to execute an INSERT, UPDATE or DELETE without returning something, you should use executeUpdate().
Statement#executeUpdate() is meant for that purpose
String query = "INSERT INTO category VALUES (" + next + ", 'Mystics', now());";
int noOfRows= st.executeQuery(query)
but it doesnt return a ResultSet , rather the no of rows affected that you could store into an Integer
Also your is highly vulnerable to Sql injection , try using the PreparedStatements to safeguard your code
I have a table in mysql that contain a field called template.
I have one template stored in a variable, I need to compare that variable with each of the other templates found in the table until a match is found. I dont know how to retrieve one template from the database row at a time, compare it and if it does not match, move to next row to compare again and so on until match is found. I am new to mysql looping, please help.
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "");
PreparedStatement st;
st = con.prepareStatement("select template from tbl1 ");
ResultSet result = st.executeQuery();
while (result.next()) {
String dbTemplate = result.getString("template");
if x == dbtemplate
} else {// move to next row? How to say do the loop for next row in table??
}
Ask SQL to check it for you, Try this:
st = con.prepareStatement("select template from tbl1 where template = ?");
st.setString(1, "template_name");
Then you would only have results that templates matches
result.next() any way gets next row. All you need to do would do condition check inside and if condition satisfied, then only execute the functionality you want.
while (result.next()) {
if(yourConditionSatisfied) {
//All your logic goes here. If you want to break the lookup, just add break here.
}
}
G'day!
I have one million different words which I'd like to query for in a table with 15 million rows. The result of synonyms together with the word is getting processed after each query.
table looks like this:
synonym word
---------------------
ancient old
anile old
centenarian old
darkened old
distant far
remote far
calm gentle
quite gentle
This is how it is done in Java currently:
....
PreparedStatement stmt;
ResultSet wordList;
ResultSet syns;
...
stmt = conn.prepareStatement("select distinct word from table");
wordList = stmt.executeQuery();
while (wordList.next()) {
stmt = conn.prepareStatement("select synonym from table where word=?");
stmt.setString(1, wordList.getString(1));
syns = stmt.executeQuery();
process(syns, wordList.getString(1));
}
...
This is incredible slow. What's the fastest way to do stuff like this?
Cheers,
Chris
Ensure that there is an index on the 'word' column.
Move the second prepareStatement outside the word loop. Each time you create a new statement, the database compiles and optimizes the query - but in this case the query is the same, so this is unnecessary.
Combine the statements as sblundy above has done.
Two ideas:
a) How about making it one query:
select synonym from table where word in (select distinct word from table)
b) Or, if you process method needs to deal with them as a set of synonyms of one word, why not sort them by word and start process anew each time word is different? That query would be:
select word, synonym
from table
order by word
Why are you querying the synonyms inside the loop if you're querying all of them anyway? You should use a single select word, synonym from table order by word, and then split by words in the Java code.
PreparedStatement stmt;
ResultSet syns;
...
stmt = conn.prepareStatement("select distinct " +
" sy.synonm " +
"from " +
" table sy " +
" table wd " +
"where sy.word = wd.word");
syns = stmt.executeQuery();
process(syns);
related but unrelated:
while (wordList.next()) {
stmt = conn.prepareStatement("select synonym from table where word=?");
stmt.setString(1, wordList.getString(1));
syns = stmt.executeQuery();
process(syns, wordList.getString(1));
}
You should move that preparestatement call outside the loop:
stmt = conn.prepareStatement("select synonym from table where word=?");
while (wordList.next()) {
stmt.setString(1, wordList.getString(1));
syns = stmt.executeQuery();
process(syns, wordList.getString(1));
}
The whole point of preparing a statement is for the db to compile/cache/etc because you're going to use the statement repeatedly. You also may need to clean up your result sets explicitly if you're going to do that many queries, to ensure that you don't run out of cursors.
You should also consider utilizing the statement object's setFetchSize method to reduce the context switches between your application and the database. If you know you are going to process a million records, you should use setFetchSize(someRelativelyHighNumberLike1000). This tells java to grab up to 1000 records each time it needs more from Oracle [instead of grabbing them one at a time, which is a worst-case-scenario for this kind of batch processing operation]. This will improve the speed of your program. You should also consider refactoring and doing batch processing of your word/synonyms, as
fetch 1
process 1
repeat
is slower than
fetch 50/100/1000
process 50/100/1000
repeat
just hold the 50/100/1000 [or however many you retrieve at once] in some array structure until you process them.
The problem is solved. The important point is, that the table can be sorted by word. Therefore, I can easily iterate through the whole table. Like this:
....
Statement stmt;
ResultSet rs;
String currentWord;
HashSet<String> syns = new HashSet<String>();
...
stmt = conn.createStatement();
rs = stmt.executeQuery(select word, synonym from table order by word);
rs.next();
currentWord = rs.getString(1);
syns.add(rs.getString(2));
while (rs.next()) {
if (rs.getString(1) != currentWord) {
process(syns, currentWord);
syns.clear();
currentWord = rs.getString(1);
}
syns.add(rs.getString(2));
}
...