HasbroIssuanceDateData data1 = extractedDateData.get(c);
if (data.getOpeningBankReference().equals(data1.getOpeningBankReference())) {
data1.getOpeninbankRefernce();
data1.getPoNumber()).concat(DELIMETER));
}
I have a very simple question. I want to run a loop inside the if statement to get all rows that satisfy the if condition. Since there can be multiple rows with the same data1.getOpeningBankReference(). How would I do that?
For example in data1 there are 100 rows. I want that once it enters the if statement, it will give me all 5 rows as results (assuming there are 5 rows with the same OpeningBankRef) where data.getOpeningBankReference().equals(data1.getOpeningBankReference()) and then exit the if statement.
Maybe you need your for outside the if and another inside. So you can compare all the rows with your data.getOpeningBankReference()
for (Row row: rows) {
HasbroIssuanceDateData data1 = extractedDateData.get(row);
if (data.getOpeningBankReference().equals(data1.getOpeningBankReference())) {
for (Row anotherRow: anotherRows) {
//here you have all the rows you need.
}
}
}
Related
I have 2 ResultSets. 1st ResultSet contains the records from table1 from database1 and 2nd ResultSet contains the records from table2 from database2. I need a list of records from resultset1 which are not present in resultSet2. For this I wrote this logic but it is not working and throwing me the following error.
java.sql.SQLException: Invalid operation for read only resultset: deleteRow
if ( table1ResultSet != null )
{
while ( table1ResultSet.next() )
{
final String table1Record = table1ResultSet.getString( 1 );
if ( table2ResultSet != null )
{
while ( table2ResultSet.next() )
{
final String table2Record = table2ResultSet.getString( 1 );
if ( table1Record.toString().equalsIgnoreCase( table2Record.toString() ) )
{
table1ResultSet.deleteRow();
break;
}
}
}
}
}
return table1ResultSet;
That exception says what the problem is - your result set doesn't support delete. In order to have updateable result set there are some requirements:
When you prepare statement did you make it with ResultSet.CONCUR_UPDATABLE?
A query can select from only a single table without any join operations.
The query must select all non-nullable columns and all columns that do not have a default value. A query cannot use "SELECT * ". Cannot select derived columns or aggregates such as the SUM or MAX of a set of columns.
You might want to move the results sets into Java sets before working doing what you are doing though because using deleteRow will actually delete the row from the database (unless that's the expected result)
There is another problem with your code though. Even if delete works your code will fail on the second iteration of result set 1 because you never reset table2ResultSet and for the second iteration there won't be more results in table2resulset.
But on top of all that. Why would you go through all that hussle and get all that rows that you don't need instead of doing it with one single query like:
select * from table 1 where id not in select id from table 2
or
delete from table 1 where id not in select id from table 2
if that's the goal
Your logic:
Assumes the records come in some order (which may or may not be true, depending on your SQL)
Consumes the entire result set 2 for each row of result set 1, which is unlikely your intent
Deletes things, which is also not what you mentioned in the question
Your question can be implemented easily as such:
Set<String> list1 = new HashSet<>();
while (table1ResultSet.next())
list1.add(table1ResultSet.getString(1).toLowerCase());
while (table2ResultSet.next())
list1.remove(table2ResultSet.getString(1).toLowerCase());
System.out.println(list1);
This will print all the values (without duplicates) that are present in the first result set, but not in the second.
This is a weird issue. I know I'm making a small mistake but not able to figure it out what exactly in it.
I'm executing one query and it has result set. First I'm validating if it doesn't has records then set one of the DTO attribute to false. If it has records, then iterate and do some business.
rs = partyPreparedStatement.executeQuery();
if(!rs.next()) { // It has records, but I'm checking with ! operator to make sure it goes to false or true.
purchaseDto.setPOIssued(false);
} else {
while (rs.next()) { // It has records, but still its not going to execute business
// Do some business here.
break;
}
}
Is the design correct?
If data is returned you will be ignoring the first row.
The first call to next() will already position the ResultSet to the first row (if there is data). But you don't do anything with that row, you immediately call next() again (in the while condition) thus ignoring the first row completely.
How you solve this problem is a matter of taste. I personally would simply count the number of rows processed:
If you only want to process the first row, you don't need a while to begin with:
rs = partyPreparedStatement.executeQuery();
if (rs.next()) {
purchaseDto.setPOIssued(true);
// process the data here
} else {
purchaseDto.setPOIssued(false);
}
You move the cursor two times so instead you can use do{}while loop :
if (!rs.next()) {
purchaseDto.setPOIssued(false);
} else {
do {
// Do some business here.
break;
} while (rs.next());
}
set the value default to false and in the loop to true
purchaseDto.setPOIssued(false);
while (rs.next()) { // It has records, but still its not going to execute business
// Do some business here.
purchaseDto.setPOIssued(true);
break;
}
Here is my MySql table:
I want to show the output of the query in commandline as below:
I have written the code below to loop but I am getting only the first row, What i have to modify ??
ResultSet rs2 = stmt.executeQuery(table_retrive);
String[] cols = new String[itemList.size()];
int[] rec =new int[itemList.size()];
for (int i = 0; i < itemList.size(); i++) {
while (rs2.next()) {
cols[i] =(String) itemList.get(i);
rec[i] = rs2.getInt(cols[i]);
System.out.println(rec[i]+" ");
}
}
Your two loops are wrong. Start at i=0 and then iterate once over the whole ResultSet, filling yor first array position. When this is done, i is incremented and you try to iterate the ResultSet a second time but the cursor is at the end of the ResultSet, so rs2.next() returns false and the code will not be executed.
So you have two Solutions:
Handle the loops correctly. Unfortunately I do not know, what you are trying to do anyways because this is some C-like code without OOP, which doesn't show semantics and then you have this itemList which seems to hold preset values and you read out of this list, which column to take for the i-th position. This seems odd. Maybe switching the loops does the desired: Start with the while and nest the for.
Reset the cursor of the ResultSet after the while with rs2.beforeFirst(). WARNING: This could throw a SQLFeatureNotSupportedException. Not all Databases can move the cursor backwards. This is of course a very ugly solution, since you should first parse the whole row a once.
Try to use printf() Or format() method. It is same as printf method in c lang. you can pass parameters and difference. Look at link1
And link 2
Example : System.out.printf("%d%5s%10d", 5,"|",10);
output : 5 | 10
Using this the I got all the values but in one row :
while (rs2.next()) {
for (int i = 0; i < itemList.size(); i++) {
cols[i] =(String) itemList.get(i);
rec[i] = rs2.getInt(cols[i]);
System.out.print(rec[i]+" ");
}
}
But I need to divide like the rows.
Usage of the inner loop is your problem.
You can enhance your code to remove the usage of the second loop in your code, it basically does nothing. You can loop over your result set and in the same loop using the incremented variable to persist the values accordingly.
The code shown half implemented in your question, hence it will be difficult to give you exactly what need to be done. Nevertheless, here's an attempt to resolve the problem for you:
while (rs2.next()) {
System.out.println(rs2.getInt(1) + "\t |" + rs2.getString(2) + "\t |" + rs2.getString(3));
}
Based on the column names from the table in the question, assuming that column2 and column3 are String's.
You can add the necessary details to this code to complete it according to your usecase, but I've just taken the example of showing a record in one line.
EDIT:
OP has his own way of programming, but to satisfy his question in the comment - this is how you can do it.
while (rs2.next()) {
for (int i = 0; i < itemList.size(); i++)
{
cols[i] =(String) itemList.get(i);
rec[i] = rs2.getInt(cols[i]);
System.out.print(rec[i]+"\t |");
}
System.out.println();
}
Ok that may not make much sense so I'll try and clarify with code, I've got a basic Result set like so: -
ResultSet results = stmt.executeQuery(constants.execQueueSQL());
I then want to iterate through this with a while loop like so: -
while (results.next()){
String val1 = results.getString("col 1");
String val2 = results.getString("col 2");
String val3 = results.getString("col 3");
}
Now, when I debug this within eclipse I can see that before executing the while line the currentRow is already showing as 1 in results, and as I step to each line within the while the currentRow count increases by 1!!
I know that I have 4 rows returned but by the time I get to retrieving col 3 I'm already out, and all subsequent values are wrong as they are being obtained from separate lines, why is this...?
This is the code I am working on:
if(connection.doDatabaseRead(findSQL))
{
ResultSet retRES = connection.getResultSet();
int i = 0;
// did we find anything
while( retRES.next() )
{
//read result from query
suiteNum.add(retRES.getString(i)); // this is the problem
i++;
//let other threads breathe
Thread.yield();
}
}
suiteNum is a string vector
When I try to add the database results to the vector the code crashes with this error.
java.sql.SQLException: Column Index out of range, 0 > 1.
I have the same piece of code working elsewhere in the program but I use real numbers like 0, 1 and 2 instead of i and it works fine.
As I do not know how many results the database request will have I need it to be dynamic but it will only work hard coded.
How can I make it work with i ?
The argument to getString is the column index, not the row index as you seem to think. The function returns the value of the given column in the current row, while next advances the cursor to the next row.
You probably mean:
suiteNum.add(retRES.getString(1));
in which case you can lose i altogether.
Java ResultSet objects are 1-indexed in this regard. The first element is at 1, not 0. See the javadoc.
EDIT: That's true too, but indeed the problem is this appears to be used as a row index! it's certainly the column.
This is your problem:
i = 0;
...
retRES.getString(i);
ResultSet.getString(i) gets a String from column number i
You want something like
while(retRes.next()) {
add(retRes.getString(1);
}
column index starts from 1
As I do not know how many results the database request will have I need it to be dynamic but it will only work hard coded. How can I make it work with i
ResultSetMetaData rsMetaData = rs.getMetaData();
int numberOfColumns = rsMetaData.getColumnCount();
See Also
ResultSetMetaData
Let your i start with 1 as specified in the API docs
if(connection.doDatabaseRead(findSQL))
{
ResultSet retRES = connection.getResultSet();
int i = 1;
// did we find anything
while( retRES.next() )
{
//read result from query
suiteNum.add(retRES.getString(i)); // this is the problem
i++;
//let other threads breathe
Thread.yield();
}
}