24

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.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Aswin
  • 243
  • 1
  • 2
  • 4

5 Answers5

63

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.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • bro can you give solution or idea in this question http://stackoverflow.com/questions/29014212/how-to-place-pin-mark-image-over-an-image-in-android I am very pleasure if you reply. – reegan29 Mar 16 '15 at 07:39
  • But what is the point of this if the URI has only one piece of data, like one contact? For example, I have a contact picker, and the user is picking out a contact. Thanks Mr. Hopp! – Ruchir Baronia Jan 30 '16 at 04:59
  • @RuchirBaronia - The point is to handle all cases in a uniform manner. It can't be written to always be positioned at the first entry because the result set may be empty. If it were designed so that a `Cursor` was positioned at the first entry in the sole case that the result set had a single element, the API would be much more difficult to use, requiring one to always write code to handle that case separately. – Ted Hopp Jan 30 '16 at 23:44
16
if (c.moveToFirst()) {
  while(!c.isAfterLast()) { // If you use c.moveToNext() here, you will bypass the first row, which is WRONG
    ...
    c.moveToNext();
  } 
}
macio.Jun
  • 9,647
  • 1
  • 45
  • 41
  • Thanks to this, I'm able to resolved my problem where my first item is always missing from my list. – kabayaba Sep 26 '19 at 03:51
0

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.

Bob
  • 22,810
  • 38
  • 143
  • 225
0

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(); 
WaterRocket8236
  • 1,442
  • 1
  • 17
  • 27
-1

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.

hgg
  • 1
  • 1
    Please check the logical error: If cursor.moveToNext returns true, then you are on first record. Calling moveToNext will skip your first row to the next row and your first row will never be accessed. After you check that moveToFirst returns true, your while loop will be a do {}while() loop instead of while loop. – Abhinav Saxena Aug 19 '16 at 03:58