Nelson Silva
Nelson Silva

Reputation: 439

CursorIndexOutOfBoundsException on SQLite get

I want to get data from an SQLite table and I know that table will always have only one record. I'm trying to do that get using:

public User_Token getUser_TokenDB() {

    String sql = "SELECT * FROM " + TABLE_NAME_USER_TOKEN  +" WHERE ID = " + 1;

    Cursor cursor = this.database.rawQuery(sql, null);

User_Token auxUserToken = new User_Token(
        cursor.getLong(0),
        cursor.getString(1),
        cursor.getString(2),
        cursor.getString(3));

return auxUserToken;
}

But I always get:

'java.lang.RuntimeException: Unable to start activity ComponentInfo{com.support.android.iplfit/com.support.android.iplfit.Activities.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0'.

The only way I can access this information is by returning an array of Tokens and do .get(0) but I feel like it is not the right way, since it has no sense to return an array of only one object.

Upvotes: 0

Views: 44

Answers (3)

MikeT
MikeT

Reputation: 56943

You aren't moving to a position within the cursor, thus the location is before any rows i.e. -1.

You need to move to a row and in your case you want the first row (not that there are any (i.e. the message says size of 0)) and only if the move can be made do you want to extract data. Otherwise you would handle no data available.

The Cursor move???? methods (moveToFirst, moveToLast, moveToNext, moveToPrevious, moveToPosition) all return true if the move can be made, otherwise false.

So your code code be :-

Cursor cursor = this.database.rawQuery(sql, null);
if (cursor.moveToFirst) {

    User_Token auxUserToken = new User_Token(
    cursor.getLong(0),
    cursor.getString(1),
    cursor.getString(2),
    cursor.getString(3));
} else {
  return null; //???? handle no data how you want perhaps null.
}
return auxUserToken;

As a note it's inadvisable to generally use column offsets, rather the more common way is to get the offset according to the column name using getColumnIndex(column_name). So (assuming the column name is id) would be to replace cursor.getLong(0) with cursor.getLong(cursor.getColumnIndex("id")

Upvotes: 1

Yousaf
Yousaf

Reputation: 29282

You need to move cursor at first row before you can get data from it. Call moveToNext method before accessing data from cursor

while(cursor.MoveToNext()) {
    User_Token auxUserToken = new User_Token(
        cursor.getLong(0),
        cursor.getString(1),
        cursor.getString(2),
        cursor.getString(3));
} 

Upvotes: 1

DeeV
DeeV

Reputation: 36035

The cursor index starts out of bounds. You need to use Cursor#moveToFirst() which moves the cursor to the 0 index and returns true if there are items in the cursor.

So something like this:

if (cursor.moveToFirst()) {
   // Cursor has items and is ready for extraction
} else {
   // Cursor has no items.
}

Upvotes: 1

Related Questions