Get 2 consecutive rows of a resultset - java

I need to compare a row of a ResultSet with the consecutive row if the row string matches a particular string.
while(rs.next())
{
String name = rs.getString("name");
if(name.equalsIgnoreCase("SomeName")
{
String nextName = //code to get the next consecutive row
if(nextName.contains(name)
{
name = "NA";
}
}
stringList.add(name);
}
How can I get the next row while the cursor is still on that row?

Approach hint: try storing the first one in a variable and then compare when reading the next row.
Really teaching you how to fish here, not handing you the catch.

To flesh this out (a little):
String lastName = null;
while (rs.next()) {
// do stuff with this row
if (name.equalsIgnoreCase("SomeName") && lastName != null) {
// work with lastName & SomeName
}
// save/assign lastName
}

You can use rs.next(), rs.getString() and then rs.previous() to move one row forward.
However a better option would be to memorize previous string value in a local variable and compare it at the next iteration.

Hint: Try to store first row value then use another loop and compare that value.
Hint: use nested loop

Related

android : cursor ignores first row in table

i have a database and i want to use a cursor to collect all objects of one column in a string[]... so here is my code:
c.moveToFirst();
int i = 0;
String[] addresses = new String[c.getCount()];
while(c.moveToNext()) {
addresses[i] = c.getString(c.getColumnIndex("address"));
i++;
}
c.close();
but when I used this code:
StringBuilder builder = new StringBuilder();
for(String in : addresses) {
builder.append("" + in + " ");
}
Toast.makeText(getApplicationContext(), builder, Toast.LENGTH_LONG).show();
for showing all objects in my string[], I got this:
234567null.. but right answer should be like this : 1234567 ..!
so where is my mistake?? ... thanks!!
tl;dr Remove the call to moveToFirst() and it will work.
A new Cursor starts out at position -1 and by calling moveToFirst it will move to position 0.
If you use while(moveToNext) after calling moveToFirst the first index accessed in the loop will be 1, skipping 0.
Cursor loops are best done just using
cursor.moveToPosition(-1); // in case you accessed it before
while(cursor.moveToNext()) {
// ...
}
cursor.close();
This is an option for using cursor:
if (c != null && c.moveToFirst()) {
do {
// read your cursor params
} while (c.moveToNext());
}
You dont need the:
c..moveToFirst();
The cursor starts from before the first result, and moveToNext will take it to the first row.
The way you have written it, the cursor skips the first row as moveToFirst takes it to 1st row and then moveToNext takes it to the 2nd. Thus the addresses has one string less in the end and it gives null as u have fixed the length of the array. You would have got 234567 if you would have used a list which would have made it clear that it skips the first.

Why is this variable set to empty string when it is already initialized to an empty string?

I have taken the following code snippet from the 5th snippet on this developer guide on Content Providers.
The confusion is that in the first statement String[] mSelectionArgs = {""};, mSelectionArgs[0] IS set to "".
Then later if the mSearchString is empty (TextUtils.isEmpty(mSearchString)), then again mSelectionArgs[0] is assigned "".
So the question is that why are they setting it to an empty string when it is already initialized to an empty string?
/*
* This defines a one-element String array to contain the selection argument.
*/
String[] mSelectionArgs = {""};
// Gets a word from the UI
mSearchString = mSearchWord.getText().toString();
// Remember to insert code here to check for invalid or malicious input.
// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
// Setting the selection clause to null will return all words
mSelectionClause = null;
mSelectionArgs[0] = "";
} else {
// Constructs a selection clause that matches the word that the user entered.
mSelectionClause = UserDictionary.Words.WORD + " = ?";
// Moves the user's input string to the selection arguments.
mSelectionArgs[0] = mSearchString;
}
...
I like it, because it's symmetric
if something
var = x
else
var = y
It's clear what var is under each condition, without needing to go back and visit its initial value.
Except for additional clarity and code readability, as noted in another answer, this coding style makes for a less error prone code which is easier to maintain.
This way, if the initial value of mSelectionArgs is changed, or new code added which overrides this value before the execution of the if-else block, the code of this block will still execute correctly. Without this "rudimentary" assignment, a change as described above could lead to a bug which would be very difficult to trace.
As a side note:
This specific code snippet is not that good (yes, I know it is from Android Developers site...) - if you pass null as selection argument to query(), then it is better to also pass null as selectionArgs argument. I'd modify this sample to something like this (setting both selection and selectionArgs to null):
// Gets a word from the UI
mSearchString = mSearchWord.getText().toString();
// Remember to insert code here to check for invalid or malicious input.
String[] mSelectionArgs = null;
// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
// Setting the selection clause to null will return all words
mSelectionClause = null;
mSelectionArgs = null;
} else {
// Constructs a selection clause that matches the word that the user entered.
mSelectionClause = UserDictionary.Words.WORD + " = ?";
// Moves the user's input string to the selection arguments.
mSelectionArgs = new String[] {mSearchString};
}
Edit: why the above code snippet is better than the original one?
It is not an error to pass null as selection and non-null as selectionArgs. This array will be passed to the specific ContentProvider you're addressing, and shouldn't be used at all since selection does not contain any ? placeholders. Any ContentProvider violating this assumption is buggy. Although not an error, it just looks weird - why do you pass an object that should be ignored anyway? This also has performance cost (which is higher if ContentProvider runs in different process), which is proportional to the size of the object being passed.
Edit 2: why the above code snippet is MUCH better than the original one?
Turns out that what I said above might be misleading. I found it out the hard way:
Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 3 because the index is out of range. The statement has 1 parameters.
at android.database.sqlite.SQLiteProgram.bind(SQLiteProgram.java:212)
at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:166)
at android.database.sqlite.SQLiteProgram.bindAllArgsAsStrings(SQLiteProgram.java:200)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
The above exception was thrown because I tried to pass selectionArgs which contained more elements than the number of ? placeholders in selection.
These two methods from SQLiteProgram.java are to "blame" for this exception:
public void bindAllArgsAsStrings(String[] bindArgs) {
if (bindArgs != null) {
for (int i = bindArgs.length; i != 0; i--) {
bindString(i, bindArgs[i - 1]);
}
}
}
private void bind(int index, Object value) {
if (index < 1 || index > mNumParameters) {
throw new IllegalArgumentException("Cannot bind argument at index "
+ index + " because the index is out of range. "
+ "The statement has " + mNumParameters + " parameters.");
}
mBindArgs[index - 1] = value;
}
Now, when I found out about this behavior, I think that the code example from Android Developers site is not just inefficient, but is a total crap!
Bottom line: if you pass null as selection, pass null as selectionArgs as well. If selection is not null and contains ? placeholders - make sure that the length of selectionArgs array equals the number of ? placeholders in selection.

How can i get another string from select query?

I want to get string from column no. 4 from my database to check user privileges.
Can I use rs.getString(index) to get data from column no.4?
I want to check user´s privileges...so if the column data is equal 4, the page will be redirected to AdminControlPanel.jsp
BUT, this code doesn´t work :(
String user=request.getParameter("login");
String pass=request.getParameter("password");
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/android","root","root");
Statement st=con.createStatement();
ResultSet rs=st.executeQuery("select * from users where login='"+user+"' and password='"+pass+"'");
String p = rs.getString(4);
int count=0;
while(rs.next()){
count++;
}
if(count>0 && p == "4"){
// out.println(rs);
response.sendRedirect("AdminControlPanel.jsp");
}
else{
out.println("aaa");
response.sendRedirect("#");
}
}
catch(Exception e){
System.out.println(e);
}
you are comparing two String objects rather than checking the values in the String.
just change the code to p.equals("4") and try.
String p = rs.getString(4); // This should be inside your while
int count=0;
while(rs.next()){
count++;
}
You should move your first line inside your while loop. You can't
fetch the columns of a row, until you move your cursor to that row
using res.next().
Also, since your database should ideally have only one record for a
combination of username and password. So, you can better use an
if instead of while.
And you don't really need a count variable there.
So, your code should be: -
ResultSet rs=st.executeQuery("select * from users where login='"+user+"' " +
"and password='"+pass+"'");
if (rs.next()) {
String p = rs.getString(4); // Note that using Column name is a better idea
// or rs.getInt(4) if the column type is `int`
if(p.equals("4")) { // Use equals method to compare string content
response.sendRedirect("AdminControlPanel.jsp");
} else{
out.println("aaa");
response.sendRedirect("#");
}
}
Also, note that you should compare your string using equals method. if (p == "4") will give you false result. == operator does not compare the content of the string, rather the content of the reference used in comparison.
You want
while (rs.next()) {
String val = rs.getString(4);
....
Note that iterating through a ResultSet iterates through the rows. For each row, the column indexing starts from '1'.
However it's safer to get by column name, since your SQL query doesn't specify neither the columns nor the order in which they're returned:
String val = rs.getString("COLUMN_NAME");
I see from the below that you need an integer. Check out the doc for ResultSet for more info, but:
int val = rs.getInt("COLUMN_NAME");
As an aside, I don't see you closing your ResultSet/Statement/Connection in the above. If you're not, then you'll need to!

Get separate record for each value

I have a list, List<String> myList=new ArrayList<String>(); This list contains the list of countries that I am dealing with.
I am dealing with several records. I need to calculate in such a way that a separate entry for records as per country is sorted.I am using the following logic
for(int zTmp = 0; zTmp<myList.size(); zTmp++)
{
System.out.println("COUNTRY IS"+myList.get(zTmp));
if((record).contains(myList.get(zTmp)))
{
// my next step
}
}
How ever I find that each and every record is entering after the if condition. The records are alphabetically sorted as per countries, and records of every country are together. Please correct me.
This is my String
RECORD 1#India$
RECORD 2#India$
RECORD 3#United Arab Emirates$
RECORD 4#United Arab Emirates$
RECORD 5#United Kingdom$
Sorted as per country name.
I need to give a condition such that it enters in the loop for every country ie say RECORD 1,RECORD 2 calculation must be done break; record 3 ,4 break; record 5 like this.
Hope I am more clear now.
Maybe you mean this?
String currentCountry = "";
for (String record : myList) {
// Regex for entire string "^....$"
// Country between '#' and '$' (the latter escaped)
String country = record.replaceFirst("^.*#(.*)\\$$", "$1");
if (!country.equals(currentCountry)) {
currentCountry = country;
... // Deal with next country
}
}
for(int zTmp = 0; zTmp<myList.size(); zTmp++)
{
System.out.println("COUNTRY IS"+myList.get(zTmp));
if((record).contains(myList.get(zTmp)))
{
// my next step
}
}
Your if condition will result in false only if record doesn't contain a country which is not present in complete myList, otherwise It will be true atleast in one iteration.
In comments you wrote:
You want to calculate 3 records
instead of using myList, create a separate list (say myChoosenCountriesList) of having those countries only when you want if condition to become true.
Then replace your code with following: (Note other improvments also)
int countryCount = myChoosenCountriesList.size();
for(int zTmp = 0; zTmp<countryCount; zTmp++)
{
String countryName = myChoosenCountriesList.get(zTmp);
System.out.println("COUNTRY IS"+countryName);
if(record.contains(countryName))
{
// my next step
}
}
The desired output has been achieved by using do while loop
here is the snippet
int zTmp=0;
do
{
String country=myList.get(zTmp);
if(inputCountry.equals(country))
{
CalcDays(tmpTokens[iTmp]);
myDateList.clear();
}zTmp++;
}while(zTmp<myList.size());

java.lang.IndexOutOfBoundsException: Index: 4, Size: 4

How can I fix this OutOfBoundsException?
Here is the code I am using:
ResultSet rsTagCheck = stmt.executeQuery(
"SELECT PARKING.XKRPRMT.XKRPRMT_PIDM, PARKING.XKRPRMT.XKRPRMT_STATUS, PARKING.XKRPRMT.XKRPRMT_EXPIRE_YR, PARKING.XKRPRMT.XKRPRMT_TAG FROM PARKING.XKRPRMT WHERE XKRPRMT_PIDM ='" + BannerID + "'");
while (rsTagCheck.next()){
String TagNum = rsTagCheck.getString("XKRPRMT_TAG");
ArrayList<String> myTag = new ArrayList<String>();
for (int i = 0; i < TagNum.length(); i++){
myTag.add(TagNum);
myTag.get(i + i);
I kinda know why I am getting the error, but I am not sure how to remedy the problem.
The problem is the i+i part in myTag.get(i+i). It'll work for i=0, but as soon as i=1, you'll get an exception thrown, since you've added two elements to myTag, but are accessing the third element (myTag.get(2)).
What is it that you expect myTag.get(i + i) to do?
The first time through the loop, "i" is zero and you add one element. There won't be an element 1, so the call will throw an exception. Now that I actually see what you wrote, it'll fail on the second iteration, not the first, as poor #Giu noted in his now-deleted answer. Still, it's weird and I don't know what you're trying to accomplish by calling .get() and not even looking at the return value.
You really will have to explain what it is you're trying to do, because that doesn't really make any sense as written. Did the exception in the question title really come from that code, or did you edit part of it out when posting?
edit — whoops totally saw "i+i" as "i+1". Still makes no sense to me however.
You are using the for loop by iterating on the String TagNum. You should only need to say: myTag.add(TagNum).
Imagine that the String TagNum has 4 characters. You add the String to the list 4 times, but when you reach i = 3, you are trying to retrieve the element at position 3 + 1, but the list has elements from 0 to 3.
Also, try replacing the BannerID with a ? and set the parameter to the statement accordingly.
This myTag.get(i + i); is causing the exception.
First time in the loop i is 0, you add an item into the ArrayList and then call get(0+0) which is fine.
In the next iteration, you add another element(total of 2 element in the list now) and call get(1+1), this causes exception as you have only 2 elements and valid index are 0 and 1.
Even without the problem with the get, your program as written will read through the results of the query, and then for each CHARACTER in tagNum, it will add an instance of tagNum to your array. So if tagNum is, say, "ABC", the array will end up containing "ABC" three times. If tagNum is "ABCD", it will contain "ABCD" four times. This doesn't make a lot of sense.
I think what you want is to just add tagNum to an array, defining the array OUTSIDE of the ResultSet.next loop. Something like this maybe:
ArrayList<String> myTag = new ArrayList<String>();
ResultSet rsTagCheck = stmt.executeQuery(
"SELECT PARKING.XKRPRMT.XKRPRMT_PIDM, PARKING.XKRPRMT.XKRPRMT_STATUS, PARKING.XKRPRMT.XKRPRMT_EXPIRE_YR, PARKING.XKRPRMT.XKRPRMT_TAG FROM PARKING.XKRPRMT WHERE XKRPRMT_PIDM ='" + BannerID + "'");
while (rsTagCheck.next()){
String TagNum = rsTagCheck.getString("XKRPRMT_TAG");
myTag.add(TagNum);
}
(Of course this doesn't use any of the other data in your query and I don't know what all else you're up to, but I believe that's what you're trying to do for this part.)
Update
Suppose you have ten records in your database table. After the above loop is complete, the array should be populated.
Try something like this:
ArrayList<String> myTag = new ArrayList<String>();
ResultSet rsTagCheck = stmt.executeQuery(
"SELECT PARKING.XKRPRMT.XKRPRMT_PIDM, PARKING.XKRPRMT.XKRPRMT_STATUS, PARKING.XKRPRMT.XKRPRMT_EXPIRE_YR, PARKING.XKRPRMT.XKRPRMT_TAG FROM PARKING.XKRPRMT WHERE XKRPRMT_PIDM ='" + BannerID + "'");
while (rsTagCheck.next()){
String TagNum = rsTagCheck.getString("XKRPRMT_TAG");
myTag.add(TagNum);
}
for (String tag : myTag)
{
System.out.println(tag);
}
That should give you the list of all the tags. Note you have to examine the List AFTER the while(ResultSet) loop ends. Inside the loop you will only have the elements read so far.
If you're still getting only one value, make sure that you have more than one record coming back from the result set. Like, run the query outside of a Java program and see how many records you get.
List<WebElement> div1=driver.findElements(By.xpath(".//*[#class='art_title']"));
for(int i=0;i<=div1.size();i++)
{
System.out.println(div1.get(i).getText());
Thread.sleep(1000);
}
Instead of the above format I changed it into this format :
List<WebElement> div1=driver.findElements(By.xpath(".//*[#class='art_title']"));
String[] abc = new String[div1.size()];
int i= 0;
for (WebElement e : div1)
{
abc[i] = e.getText();
i++;
System.out.println(e.getText());
}

Categories