I am working to extract the data from database. Please find the code below:
I am using "org.springframework.jdbc.support.rowset.SqlRowSet" from Springframework.jdbc.
String query="SELECT * from TABLE_NAME where id=? and password=?";
args.add(userId);
args.add(password);
SqlRowSet rs = this.jdbcTemplate.queryForRowSet(query, args.toArray());
while (rs.next()) {
---Some Code---
}
rs.next() is true, but it is not going into the loop. Need some help on how to overcome this issue. Any help is appreciated.
This is just a guess, but since you know that rs.next() returns true, it means you executed it (either in debug mode or printed to console or whatever).
Every time you execute it, it advances the rowset to the next row, if there is one. If your rowset contains only 1 row, and you "check" the value returned by rs.next() before the loop, the loop will never be entered because when it's called again there are no more rows, so it returns false.
I don't the reason for that. But I have changed the implementation. I have changed the while loop to for loop by getting the size from the resultSet. Thanks a lot for your suggestions.
int size =0;
if (rs != null)
{
rs.beforeFirst();
rs.last();
size = rs.getRow();
}
for (int i =0;i<size;i++){//Do SOMETHING}
Related
I have a select SQL that may get many rows of data.
And I only want the first 5 rows.
Besides adding rownums = 5 or adding statement.setMaxRows(5).
Can I get the result from using java coding?
Thanks.
I tried for loop and while(rs.next() && i < 5). all of them does not work.
try (Connection connection = abc.getConnection();
PreparedStatement statement = connection.prepareStatement(sql))
{
statement.setString(1,idNum);
ResultSet rs = statement.executeQuery();
for (int i = 0; i < 5; i++) {
while (rs.next()) {
itemList.add(rs.getString("idName"));
}
}
}
It shows all of the result in the itemList from the select SQL.
Currently, a single iteration of your loop exhausts the whole resultset.
You may want to add up end conditions like :
for (int i = 0; i < 5 && rs.next(); i++) {
itemList.add(rs.getString("idName"));
}
Note that your attempt with while(rs.next() && i < 5) should also work, you were probably just missing the increment of i .
You can read only the first 5 rows from the resultSet on the client side, but ideally you should be limiting number of rows returned by the database. Use limit 5 in the query.
This will avoid a lot of unnecessary work needed to return those extra rows from the database to client.
Your query is responsible to fetch data from DB , so better to control retrieve rows from db itself, this will avoid your java code checks. use limit 5 in your query based on your requirements.
I want to select the maximum line number from my database "Logs" and store it in a variable m.
Here's my code:
ResultSet rs = stmt.executeQuery("Select max(Line) as L from logs");
while (rs.next()) { // Why do I need this
int m = rs.getInt("L");
System.out.println(m);
}
But it doesn't work unless I use while(rs.next()).
If I understand correctly, rs.next() moves the cursor to the next row, but here, in this result, I only have one row.
So, can someone explain why the loop is necessary? The only thing I can think of is that the first cursor is set on the column name, am I right?
Why?
The cursor is initially placed before the first element. You need to advance it once to access the first element.
This was obviously done because traversing the results using a loop is very convenient then, as you see. From the official documentation:
Moves the cursor forward one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.
Solution
So, while you don't need any loop, you need to advance the cursor once. A single rs.next(); would technically be enough:
rs.next();
// Access the result
However, you probably want to account for the case where there was no match at all, since:
When a call to the next method returns false, the cursor is positioned after the last row. Any invocation of a ResultSet method which requires a current row will result in a SQLException being thrown.
So the code would fail in this case.
Because of that, you should account for the case and use the returned boolean to guard your access:
if (rs.next()) {
// Access result ...
} else {
// No match ...
}
From the official documentation (which you should have read btw):
Initially the cursor is positioned before the first row. The next method moves the cursor to the next row, and because it returns false when there are no more rows in the ResultSet object, it can be used in a while loop to iterate through the result set.
You basically need to move it, in your case moving it once is enough:
rs.next();
System.out.println(rs.getInt("L"));
You can convert this to use a simple if statement instead.
if(rs.next()) {
// other code here
}
You would use while when you have more than one row to bring back.
A ResultSet cursor is initially positioned before the first row, the
first call to the method next makes the first row the current row, the
second call makes the second row the current row, and so on.
consider you have something like this.
->1->2->3
^
your "rs" is initially pointed before 1, when you call rs.next() it advances the arrow to point to 1
->1->2->3
^
so if you do not call the next() method then you do not get the result.
Hope this helps
There are different types of Executing the Commands. Cursors are used to read the data from your executed queries. When you execute to Read, you using Forward Only Cursor by default hence you are only getting next result after calling Recorset.Next() ! I don't want to go in much deeper here. You can read about cursors here : https://learn.microsoft.com/en-us/sql/ado/guide/data/types-of-cursors-ado?view=sql-server-2017
The best solution in your case is to use Scalar Resultset which will return only ONE CELL thats exactly what you want to implement without having to loop through your result set. Following example shows how you can implement such :
using System;
using System.Data;
using System.Data.SqlClient;
class ExecuteScalar
{
public static void Main()
{
SqlConnection mySqlConnection =new SqlConnection("server=(local)\\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI;");
SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText ="SELECT COUNT(*) FROM Employee";
mySqlConnection.Open();
int returnValue = (int) mySqlCommand.ExecuteScalar();
Console.WriteLine("mySqlCommand.ExecuteScalar() = " + returnValue);
mySqlConnection.Close();
}
}
We are using ExecuteScalar to return only ONE Cell. Remember, Even if your Query returns Multiple Rows/Columns, this will only returns VERY FIRST CELL always.
I have a problem with retrieving data from Oracle database. I use ojdbc8 and my code is:
Statement stmt = conn.createStatement();
stmt.setFetchSize(20000);
ResultSet rs = stmt.execute(sql);
while(rs.next()) {
for(int i = 0; i < columnCounter; i++) {
logger.info(rs.getString(i) + " ");
}
}
What I don't understand here is that when my query returns let say 53000 rows all together then in while loop first 40000 rows are printed in console very quickly but then there is a huge 20-25 seconds break, nothing happens and after that the rest rows are printed. It is always like that. If my query returns 81000 rows then 80000 rows is printed very quickly then long brake and then missing 1000 rows.
So I don't know why but it looks like when in ResultSet I have exactly 20000 rows which is a fetch size then it goes well, but if the ResultSet has less than number set in FetchSize then it slow downs. Can anyone explain what is going on here and how to fix it to get rid of this huge gap/brake??
I have a simple query that returns only count of rows.
select count(*) cnt from table
I can read it by iterating through resultset.
like
while(rs.next()){
int rowCount= rs.getInt(cnt);
}
But is there any way,using which I can get count directly without looping.
How about:
int rowCount = rs.next() ? rs.getInt(cnt) : -1;
It doesn't save you much though
I am doing a simple query which I know is good and syntactically correct (no exceptions caught on executing it and the ResultSet is returned).
However when I pass this result set to a method to loop through it and perform some operations, the program is stuck looping on the first row in this result set (infinite loop). I really can't figure out what this problem could be. If the query is good, the ResultSet has the right results (I can't see what's inside it via debug as such but it should be correct) so what can be the problem?
This is the code for a better picture of what I'm doing.
ResultSet rs3 = null;
if (linked == J.LINKED_TO_ORG) {
Vector<Integer> linkedTicketIds = new Vector<Integer>();
while (rs.next()){
// returns a set of id's for linked tickets
Vector<Integer> linkedToTicket = Ticket.get_linked_OrgTickets(con, rs.getInt(Ticket.FLD_ID));
if (!linkedToTicket.isEmpty()) {
// if there are linked tickets in the result set, add them to vector
// so they can be outputted alone
linkedTicketIds.add(rs.getInt(Ticket.FLD_ID));
}
}
if (!linkedTicketIds.isEmpty()){
rs3 = select_linked_or_unlinked(con, linkedTicketIds, select_from);
}
}
In select_linked_or_unlinked method the following query is built using a string buffer and the vector linkedTicketIds which returns good results as shown (formatting added to improve readability):
SELECT Tick.ID
, Tick.DESCRIPTION
, Tick.TICKETTYPE
, States.SHORT_NAME as state
, Pri.DESCRIPTION as priority
, Owners.Login as Owner
, Submitters.Login as Submitter
, types.SHORT_NAME as type
, Tick.TITLE
, Proj.Name as Project
, Proj.ID
, Tick.RELEASE_NUM as Release
, Tick.SUBMIT_DATE
, Tick.CUSTOMER
, rownumber() OVER (ORDER BY Pri.ZORDER DESC)
as ROW_NEXT
FROM HOBTRACK.Tickets_Customers_View Tick
, HOBTRACK.PROJECTS Proj
, HOBTRACK.PRIORITIES Pri
, HOBTRACK.STATES States
, HOBTRACK.USERS Owners
, HOBTRACK.USERS Submitters
, HOBTRACK.TICKETTYPES types
, HOBTRACK.SECURITY_LEVEL Security
WHERE Tick.ID IN (25031,25100,18123)
This is how the query is executed and returned:
Statement stmt = con.createStatement(); // where con is the connection
rs = stmt.executeQuery(above_query);
return rs;
Finally, the returned result set rs3 is passed to a method where while (rs.next()) is used to loop through this result set and perform operations. This is where the program gets stuck. Any Ideas on what can be the problem or how can I identify it?
Thanks for your help :)