why c.moveToFirst() won't skip the first row - android

I always use the code below to get all the informations
But I have question that c.movetoNext lead to skip the first row of result set
Please tell me what really happens behind the surface so that I can fully understand it
SQLiteDatabase db;
Cursor c = db.query("pic", null, null, null, null,null, null);
c.moveToFirst();
while(c.movetoNext)
{
//do something
//example: String a=c.getString(0);
}

You're calling moveToFirst(), which positions the cursor on the first row, then your while loop calls moveToNext() before entering the loop, which results in the first row being skipped.
You can solve it with either a do...while loop, or a for loop such as
for( c.moveToFirst(); !c.isAfterLast(); c.moveToNext() ) {
// Stuff
}

A late answer, but hopefully useful to others finding this page. I've been using an: "if () do { } while();" loop. The "moveToFirst()" function returns false if no rows were returned in the cursor. The "moveToNext()" function returns false when past end of cursor:
Cursor c = db.query(......);
if (c.moveToFirst()) do {
data = c.getString(0) // eg. get value from first column in cursor
// do something more
} while (c.moveToNext());
c.close();
(which is similar to TactMayers' answer).

According to the Cursor documentation, "query... Returns: A Cursor object, which is positioned before the first entry". It further seems that queries get executed only when methods are called on the cursor. Hope that helps.

c.moveToFirst();
This line move the cursor to the first row.
while(c.movetoNext)
After running this line of code, the cursor will move to next row (row 2 for the first run of the while loop.) So by the time the code enter the loop, the cursor is pointing to row 2 already and can never access the first row.
Try replacing the while loop like this
do {
// do something
} while(c.movetoNext())

Actually, you do not have to call c.moveToFirst(); at all

Related

sqlite cursorindexoutofbound exception

in my android application i used the following function to retrieve the column from the table..the table contains value but it has an exception.
public String[] getactivelist(){
Log.v("ppp","getactivelist");
String[] actname=new String[50];
SQLiteDatabase db = this.getWritableDatabase();
Log.v("ppp","dbcrtd");
Cursor cursor = db.rawQuery("SELECT name FROM activelist ORDER BY time ASC", null);
Log.v("ppp","aftrcurser");
int i=0;
Log.v("ppp crsr",cursor.getString(0));
if (cursor.moveToFirst()) {
do {
actname[i]=cursor.getString(0);
Log.v("ppp crsr",cursor.getString(0));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return actname;
}
the log cat shows the following error
04-04 01:19:41.170 2581-2601/com.example.pranavtv.loudspeaker V/pppīš• tryandroid.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 2
In your line
Log.v("ppp crsr", cursor.getString(0));
You try to get a string from the cursor. If there aren't any lines, it should throw the error observed.
You are calling the following line...
Log.v("ppp crsr",cursor.getString(0));
...before you have moved the position of your Cursor using...
if (cursor.moveToFirst()) {
By default, the position of a Cursor is initially set to be -1 which is before the first valid position as the first position which contains data is position 0.
Simply remove that line (the one before the if(...)) and you should be good to go.
On another note, in your do...while loop you are using...
actname[i]=cursor.getString(0);
...but you never increment i. Consequentially you will only ever modify actname[0] regardless of how many results are returned to the Cursor.

What is The use of moveToFirst () in SQLite Cursors

I am a programming newbie
and I found this piece of code in the internet and it works fine
Cursor c=db.query(DataBase.TB_NAME, new String[] {DataBase.KEY_ROWID,DataBase.KEY_RATE}, DataBase.KEY_ROWID+"= 1", null, null, null, null);
if(c!=null)
{
c.moveToFirst();
}
but I am not able to understand the use of the
if(c!=null)
{
c.moveToFirst();
}
part. What does it do exactly , and if I remove the
if(c!=null) { c.moveToFirst(); }
part, the code doesn't work.
The docs for SQLiteDatabase.query() say that the query methods return:
"A Cursor object, which is positioned before the first entry."
Calling moveToFirst() does two things: it allows you to test whether the query returned an empty set (by testing the return value) and it moves the cursor to the first result (when the set is not empty). Note that to guard against an empty return set, the code you posted should be testing the return value (which it is not doing).
Unlike the call to moveToFirst(), the test for if(c!=null) is useless; query() will either return a Cursor object or it will throw an exception. It will never return null.
if (c.moveToFirst()) {
while(!c.isAfterLast()) { // If you use c.moveToNext() here, you will bypass the first row, which is WRONG
...
c.moveToNext();
}
}
Cursor is not a Row of the result of query. Cursor is an object that can iterate on the result rows of your query. Cursor can moves to each row. .moveToFirst() method move it to the first row of result table.
moveToFirst() method moves the cursor to the first row. It allows to perform a test whether the query returned an empty set or not. Here is a sample of its implementation,
if (cursor.getCount() == 0 || !cursor.moveToFirst()) {
return cursor.getLong(cursor.getColumnIndexOrThrow(ID_COLUMN));
cursor.close();
what macio.Jun says is right!
we have code like below:
String sql = "select id,title,url,singer,view,info from cache where id=" + id;
SQLiteDatabase db = getMaintainer().getReadableDatabase();
Cursor query = db.rawQuery(sql, null);
query.moveToFirst();
while(query.moveToNext()){
DBMusicData entity = new DBMusicData();
entity.setId(query.getString(query.getColumnIndex(FIELD_ID)));
entity.setTitle(query.getString(query.getColumnIndex(FIELD_TITLE)));
entity.setSinger(query.getString(query.getColumnIndex(FIELD_SINGER)));
entity.setTitlepic(query.getString(query.getColumnIndex(FIELD_PICURL)));
entity.setInfoUrl(query.getString(query.getColumnIndex(FIELD_INFO)));
entity.setViews(query.getString(query.getColumnIndex(FIELD_VIEW)));
Log.w(tag, "cache:"+ entity.toString());
}
query.close();
query=null;
db.close();
db=null;
If we have only one record in the cache table, query.moveToFirst(); will cause that no record returns.

android cursor.moveToNext()?

I am trying to query all the columns in a table into one long text view and/or string. I know this might not be the right way to do things but I have to do this. Correct me if I am wrong, I was under the impression that move next would get the next column in the row:
Cursor c = db.get();
if(c.moveToFirst){
do{
string = c.getString(0);
}while(c.moveToNext);
}
I thought that this would get the first column and display all of its contents instead I get the first column and first row. What am I doing wrong? Is there a better or real way to get this information without using a ListView?
The simple use is:
Cursor cursor = db.query(...);
while (cursor.moveToNext()) {
...
}
moveToFirst is used when you need to start iterating from start after you have already reached some position.
Avoid using cursor.getCount() except if it is required.
And never use a loop over getCount().
getCount is expensive - it iterates over many records to count them. It doesn't return a stored variable. There may be some caching on a second call, but the first call doesn't know the answer until it is counted.
If your query matches 1000 rows, the cursor actually has only the first row. Each moveToNext searches and finds the next match. getCount must find all 1000. Why iterate over all if you only need 10? Why iterate twice?
Also, if your query doesn't use an index, getCount may be even slower - getCount may go over 10000 records even though the query matches only 100. Why loop 20000 instead of 10000?
For clarity a complete example would be as follows which I trust is of interest. As code comments indicated we essentially iterate over database rows and then columns to form a table of data as per database.
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null,
null);
//if the cursor isnt null we will essentially iterate over rows and then columns
//to form a table of data as per database.
if (cursor != null) {
//more to the first row
cursor.moveToFirst();
//iterate over rows
for (int i = 0; i < cursor.getCount(); i++) {
//iterate over the columns
for(int j = 0; j < cursor.getColumnNames().length; j++){
//append the column value to the string builder and delimit by a pipe symbol
stringBuilder.append(cursor.getString(j) + "|");
}
//add a new line carriage return
stringBuilder.append("\n");
//move to the next row
cursor.moveToNext();
}
//close the cursor
cursor.close();
}
I am coding my loops over the cusror like this:
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
cursor.getString(cursor.getColumnIndex("column_name"));
cursor.moveToNext();
}
That always works. This will retrieve the values of column "column_name" of all rows.
Your mistake is that you loop over the rows and not the columns.
To loop over the columns:
cursor.moveToFirst();
for(int i = 0; i < cursor.getColumnNames().length; i++){
cursor.getString(i);
}
That will loop over the columns of the first row and retrieve each columns value.
moveToNext move the cursor to the next row. and c.getString(0) will always give you the first column if there is one. I think you should do something similar to this inside your loop
int index = c.getColumnIndex("Column_Name");
string = c.getString(index);
cursor.moveToFirst() moves the cursor to the first row. If you know that you have 6 columns, and you want one string containing all the columns, try the following.
c.moveToFirst();
StringBuilder stringBuilder = new StringBuilder();
for(int i = 0; i < 6; i++){
stringBuilder.append(c.getString(i));
}
// to return the string, you would do stringBuilder.toString();

Help with the Android Cursor

So I have a Cursor that is getting a result from a query to the application database. I know that there is at least one correct entry in the database since I was able to retrieve the string from the row previously.
I then changed some of the logic to accommodate the result and am suddenly getting null returned when calling c.getString(0). The relevant code is posted below.
I'm new to Android and Java, so I might be missing some subtlety that's causing the problem.
Cursor c = context.getContentResolver().query(tempJobName.build(),
null, null, null, null);
for (c.moveToFirst(); c.isAfterLast() == false; c.moveToNext())
{
Log.w(TAG, c.getString(0));
if (c.getString(0).equalsIgnoreCase(jobName))
{
existed = true;
break;
}
}
You might want to add more details. But since you did find some records, the solution for your problem is easy. Could you please replace this line with this? ( First column of table might change right :))
c.getString(0);
with
int columnIndex = c.getColumnIndex(COLUMN_NAME);// You could also use getcolumnIndexorThrow variant.
c.getString(columnIndex);
if this does not work, then your table does not have the column. You are simply barking up the wrong tree.

How to retrieve data from cursor class

I need to know how to retrieve data from cursor. I need this because the ringtonemanager returns all the audio files in form of cursor object, I need to know how to retrieve the values.
Anbudan.
Once you have the Cursor object, you can do something like this:
if (cursor.moveToFirst()){
do{
String data = cursor.getString(cursor.getColumnIndex("data"));
// do what ever you want here
}while(cursor.moveToNext());
}
cursor.close();
This looks a bit better:
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
...
}
Salvador's answer will continue to fetch data from the row after the last row because moveToNext() will only return false when the cursor is pointing at the row after the last row. It will continue to iterate even if the cursor is pointing at the last row.
The correct template should be:
if (cursor.moveToFirst()){
while(!cursor.isAfterLast()){
String data = cursor.getString(cursor.getColumnIndex("data"));
// do what ever you want here
cursor.moveToNext();
}
}
cursor.close();

Categories

Resources