-2

My SQLite give me a null pointer. I am trying to write the points to the database, and to be able to read them from it. That is the complete table. There is nothing else in the table. I am getting the null pointer in the getPoints function, when I run the query. res comes out null.

Here is the code

public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub
    db.execSQL(
            "create table hour " +
                    "(id integer primary key, number integer)");
    db.execSQL(
            "create table points " +
                    "(id integer primary key, number integer)"
    );
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub
    db.execSQL("DROP TABLE IF EXISTS hour");
    onCreate(db);
}
public boolean insertPoints (int points) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put("number", points);
    db.insert("points", null, contentValues);
    return true;
}

public int getPoints() {
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor res =  db.rawQuery( "select number from points where id=1", null );
    int i = res.getInt(1);
    return i;
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
  • `rawQuery()` does not return nulls - your problem is something else. Please start by including the crash stacktrace in the question. – laalto Dec 20 '18 at 10:56

2 Answers2

0

From AS documentation:

To look at a row in the cursor, use one of the Cursor move methods, which you must always call before you begin reading values

So, you should do this:

while(res.moveToNext()) {
    int point = res.getInt(1);
    //Do your logic
}
res.close();
tomerpacific
  • 4,704
  • 13
  • 34
  • 52
0

You have two issues.

  1. You need to move the Cursor to a row (when a Cursor is returned it is positioned at before the first row) In your case as would only be expecting a single row the Cursor moveToFirst method would suit, noting that it will return true if the move was made, if not then false.

  2. You are extracting a single column as per SELECT member FROM ..... You access the columns in the Cursor using the offset, so if there is just the 1 column then the offset would be 0 not 1 ( so int i = res.getInt(1) would fail after fixing the first issue).

As such it is suggested you change :-

public int getPoints() {
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor res =  db.rawQuery( "select number from points where id=1", null );
    int i = res.getInt(1);
    return i;
}

to be

public int getPoints() {
    int i = -1; // default return value to indicate no row found and thus no data
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor res =  db.rawQuery( "select number from points where id=1", null );
    if (res.moveToFrist()) {
        i = res.getInt(0);
    }
    res.close(); //<<<<<<<<<< YOU SHOULD ALWAYS CLOSE CURSORS WHEN DONE WITH THEM
    return i;
}
  • Note that the above would return -1 if there was no row that matched the id 1. If -1 isn't a suitable value (my guess is that it would be as you can't have less than 0 points) then substitute the -1 for another value.

Additional

Rather than trying to work out offsets, it is easier and less likely to cause issues if you use the Cursor getColumnIndex(the_column_name) method to return the offset according to the column name.

As such instead of :-

i = res.getInt(0);

Using :-

i = res.getInt(res.getColumnIndex("number"));

would be recommended

Community
  • 1
  • 1
MikeT
  • 51,415
  • 16
  • 49
  • 68