i have a problem with a cursor. i created a alarm manager that pick a value to compare with another in looping.
My problem is this: if the cursor is outside of the loop this pick only my first value (if exsist only one value pick only this obviously).... if the cursor is in the loop, this pick only last value (if exsist only one value pick only this obviously).
how to fix this?
my query:
public Cursor getRegistry2()
{
return (getReadableDatabase().query(
TabRegistry.TABLE_NAME,
TabRegistry.COLUMNS,
TabRegistry._ID,
null,
null,
null,
null));
my cursor in service:
Cursor c5 = databaseHelper.getRegistry2();
c5.moveToFirst();
while(c5.isAfterLast() == false){
tipe = c5.getString(c5.getColumnIndex(TabRegistry.TYPE));
status = c5.getString(c5.getColumnIndex(TabRegistry.STATUS));
number = c5.getString(c5.getColumnIndex(TabRegistry.NUMBER));
c5.moveToNext();
}
c5.close();
thanks in advance!
As I mentioned in my comment, if you are actually trying to find a particular item you need to actually look for it.
Assuming you are looking to compare the status, you might do this:
while(c5.isAfterLast() == false){
tipe = c5.getString(c5.getColumnIndex(TabRegistry.TYPE));
status = c5.getString(c5.getColumnIndex(TabRegistry.STATUS));
number = c5.getString(c5.getColumnIndex(TabRegistry.NUMBER));
if (status.equals(comparisonString)){
break;
}
c5.moveToNext();
}
This would break out of your loop, leaving your values set for the item you were looking for.
Personally, that's a lot of computing overhead and I'd just make the query to look for the comparison value directly and then check and see if the returned cursor was empty. Much simpler.
I don't understand your problem but something that is strange for me is : while(c5.isAfterLast() == false){
Have you tried to replace by while (c5.moveToNext()) { and removing c5.moveToFirst(); ?
You should know that you are overwriting the values of tipe, status and number in case your cursor has values more than one.
Cursor c5 = databaseHelper.getRegistry2();
if(c5.moveToFirst()){
do{
tipe = c5.getString(c5.getColumnIndex(TabRegistry.TYPE));
status = c5.getString(c5.getColumnIndex(TabRegistry.STATUS));
number = c5.getString(c5.getColumnIndex(TabRegistry.NUMBER));
}while(c5.moveToNext());
}
c5.close();
Related
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;
}
so I've build a method that return an ArrayList of a class that I use on my project, the problem is that the only item that is being add to the ArrayList is the 2nd on the database. I know that because I extracted the DB File and browsed it, and also the 'c.getCount()' return a value of 2.
So I know for a fact that my DB includes 2 entries, my Cursor gets 2 entries... but for some reason he chooses to focus on the 2nd row at the beginning after I created it - and thus exiting the while loop, even thought I called c.moveToFirst();
Maybe I'm just tired and not seeng clearly what am I doing wrong... because I compared it to other methods in my code that works fine and I cannot tell the difference between them.
My method looks like this:
public ArrayList<Kiosk> getKiosks () {
ArrayList<Kiosk> kioskArrayList = new ArrayList<>();
db = dbHandler.getWritableDatabase();
String[] columns = {Tags.TAG_LOCAL_ID, Tags.TAG_ID_SERVER, Tags.TAG_NAME,
Tags.TAG_PHONE_NUMBER, Tags.TAG_CONTACT_NAME, Tags.TAG_SCHOOL_ID};
Cursor c = db.query(DatabaseHandler.TABLE_KIOSK, columns, null, null, null, null, null);
c.moveToFirst();
Log.i("tagg", "Size of the cursor is: " + c.getCount());
while (c.moveToNext()) {
Kiosk kiosk = new Kiosk();
kiosk.setLOCAL_ID(c.getInt(c.getColumnIndex(Tags.TAG_LOCAL_ID)));
kiosk.setIdServer(c.getInt(c.getColumnIndex(Tags.TAG_ID_SERVER)));
kiosk.setName(c.getString(c.getColumnIndex(Tags.TAG_NAME)));
kiosk.setPhoneNumber(c.getString(c.getColumnIndex(Tags.TAG_PHONE_NUMBER)));
kiosk.setContactName(c.getString(c.getColumnIndex(Tags.TAG_CONTACT_NAME)));
kiosk.setSchoolId(c.getInt(c.getColumnIndex(Tags.TAG_SCHOOL_ID)));
c.moveToNext();
kioskArrayList.add(kiosk);
Log.w("taggg", "Added this to the kiosk Array: " + kiosk.getName() +
"Local ID: " + kiosk.getLOCAL_ID());
}
Log.w("tagg", "getKioskhere, size of the array I sent is: " + kioskArrayList.size());
c.close();
db.close();
return kioskArrayList;
}
My log gives clearly says the cursor's size is 2 but the ArrayList is 1:
03-11 14:18:37.334: W/(18369): School id of the client is: 1
03-11 14:18:37.336: I/(18369): Size of the cursor is: 2
03-11 14:18:37.336: W/(18369): Added this to the kiosk Array: PitaKioskLocal ID: 2
03-11 14:18:37.336: W/(18369): getKioskhere, size of the array I sent is: 1
Any advice? thanks in advance
You first move to the first element:
c.moveToFirst();
Then you move to the second one, before you even processed the first one:
while (c.moveToNext()) {
Finally, you call
c.moveToNext();
within your while loop, which leads to ignoring every second entry.
Solution: remove the call within the loop, and process the first element before moving on to the second one. The easiest method would be to change while(){} to do{} while().
Set the sort order for the query. You also do a moveToNext() prior to any work.
Cursor c = db.query(DatabaseHandler.TABLE_KIOSK, columns, null, null, null, null, Tags.TAG_LOCAL_ID + " desc");
// stuff
do {
// Iterate over cursor
} while (c.moveToNext());
It looks like you are calling moveToNext() too many times.
You start at the first row with your call moveToFirst(). Then, as you enter your while loop, moveToNext() is called again. Thus, as you enter your loop you are already sitting on the second row. Then, inside the loop, you call moveToNext() and add your kiosk too the kioskArrayList.
When you hit the top of the while loop the second time, you are sitting at an index of 2, so c.moveToNext() evaluates to false, so you only add to the list once.
I'm creating an app which stores diary entries. Upon retrieving the diary entry I get a CursorIndexOutOfBoundsException, I believe it is something to do with my SELECT statement to get the information within the DB.
getDAO = new DAO(this);
Cursor showDiaryEntries = getDAO.queryDiary(Diary.DiaryItem.FULL_PROJECTION, Diary.DiaryItem.COLUMN_NAME_DIARY_TITLE+" = "+fieldTitle, null);
Long fieldDate = showDiaryEntries.getLong(1);
Long fieldTime = showDiaryEntries.getLong(2);
String fieldEntry = showDiaryEntries.getString(3);
mDate.setText(String.valueOf(fieldDate));
Log.i(TAG,"Field Date "+ fieldDate);
mTime.setText(String.valueOf(fieldTime));
Log.i(TAG,"Field Time "+ fieldTime);
mEntry.setText(fieldEntry);
Log.i(TAG,"Field Entry "+ fieldEntry);
I've been reading about this type of exception and believe it may be to do with when I getting the String/Long as I don't have a loop? Although I don't fully comprehend this.
Log Cat
03-07 07:10:59.475: E/AndroidRuntime(1471): FATAL EXCEPTION: main
03-07 07:10:59.475: E/AndroidRuntime(1471): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.democo.mydiary/com.democo.mydiary.DiaryEntryActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
I was hoping someone would be able to educate me as to what the problem is.
Thanks
Make sure you call:
showDiaryEntries.moveToFirst();
Do this before you start doing anything to the cursor. This will make sure the cursor starts at the FIRST row in the database!
first make sure your cursor is
*not null
*Then move it to first position
if(showDiaryEntries!=null && showDiaryEntries.moveToFirst())
{
//Now do waht ever u want to do with cursor
}
Above code will take care of problem you are facing now and also which you may face in future.
When you fill a cursor, it is positioned BEFORE the first record (which index is 0); now your cursor index is -1, which corresponds to no record position.
Therefore you get an error (You try to get the values from the columns of no row).
This s why you should always moveToFirst your cursor before starting to use it.
Following code is to used for how to get cursor value.
Cursor showDiaryEntries= dbh.database_function();
if (showDiaryEntries.getCount() != 0 && showDiaryEntries!=null) {
if (showDiaryEntries.moveToFirst()) {
do {
fieldEntry = showDiaryEntries.getString(showDiaryEntries.getColumnIndex("database feild name here"));
} while (showDiaryEntries.moveToNext());
}
}
i am providing string for an example. so update your function with your long and string field..
I have two buttons. One for previous and one for next sqlite database record.
Here is how i am trying to get the next record from the database.
public long getNext(int id,DataBaseHelper helper){
Story story = new Story();
Cursor cursor = story.getStories(helper, 0);
//Updated code
cursor.moveToPosition(id);
cursor.moveToNext();
return cursor.getLong(1);
//Updated code
}
The problem is that if the previous position i pass it is "1", the next position i get is "3". Why does it skip one record? It keeps on skipping one record every time. Please tell me if i'm doing something wrong since i'm new at this and i have looked everywhere but this specific issues seems to be happening to me.
UPDATE : Code edited to show a better approach(perhaps)
Remember that Cursor.getPosition() starts to count from 0. So, the first record is at index #0, the second one at index #1, ...
Take a look at the official documentation : Cursor.moveToPosition(int position)
Let take a look at your code :
(id = 1, for the example)
cursor.moveToPosition(id);
// Cursor is now on the record #1, so the second one of the list
cursor.moveToNext();
// Cursor is now on the record id+1 = #2, so the third one of the list
return cursor.getLong(1);
// Returns the value of the colon #1 of the third record
// of the list : so the record at the index #2
Ok. I have been a little wrong with the approach here. I was ignoring the fact that the cursor index starts from -1 and that the database index of my table starts from 1. So i had to subtract -1 from the id variable and it solved the problem :) Here is the code that worked for me.
public long getNext(int id,DataBaseHelper helper){
id = id - 1;
Story story = new Story();
Cursor cursor = story.getStories(helper, 0);
//Updated code
cursor.moveToPosition(id);
cursor.moveToNext();
return cursor.getLong(1);
//Updated code
}
This is a strange problem, and I hope it has a simple solution. I have a database with encrypted values. I have created a cursor that will go through each of the entries in a table, decrypt the value from the column I need, and add the value to a variable, "total". I want the sum of all of the values in the column. Here is the code:
while (c.moveToNext())
{
strTotal = c.getString(c.getColumnIndexOrThrow(KEY_TOTAL));
strTotal = sc.decrypt(strTotal);
total = Float.valueOf(strTotal) + total;
}
Now, here's the strange part. Let's suppose I have two values in the database: 2 + 4. After each is decrypted, it will correctly add them: 6. Now, if the values are equal: 2 + 2, for instance, the method returns "2" instead of "4". This happens even if it is off by a decimal (2 + 2.01 = 4.01, but 2 + 2 still outputs 2 for example).
Is there something I am missing here? Thanks!
EDIT:
I've changed the code around just to see if the decryption was the problem and it is still giving me the same result:
float total = 0;
String strTotal = "10";
while (c.moveToNext())
{
try {
//strTotal = sc.decrypt(c.getString(c.getColumnIndex(KEY_TOTAL)));
total = Float.valueOf(strTotal) + total;
} catch (Exception e) {
Log.e(TAG, "exception", e);
}
}
This code is returning "10", even though there are 3 entries in the database! It looks like if two rows in the database have the same value in the KEY_TOTAL field, it is returning less results. Here is the query:
Cursor c = mDb.query(true, DATABASE_TABLE, new String[] {KEY_TOTAL}, KEY_TYPE + "=" + t, null, null, null, null, null);
If I pull the db and open it with a sqlite browser, and SELECT all of the rows, I am getting 3 still, however.
I just checked the SQLite documentation for Android (I'm not an Android developer) and I think I found your problem. The first argument to the query method is whether to select distinct rows. Since you're passing TRUE and you're only selecting one column, duplicates will be removed from the result, which is not what you want.
Changing your call to query to the following should fix your issue.
Cursor c = mDb.query(false, DATABASE_TABLE, new String[] {KEY_TOTAL},
KEY_TYPE + "=" + t, null, null, null, null, null);
Have you checked for thrown exceptions? Especially NumberFormatException? I'm guessing there is some other logic problem that is causing the loop to exit prematurely.