Короче говоря, вы не можете получить тип столбца, если не переместитесь в допустимую строку, и это дополнительно требует, чтобы у самого курсора были строки.
Поэтому вам необходимо
проверьте, что на самом деле курсор имеет 1 или более строк (то есть он не пустой).Для этого можно использовать метод Cursor getCount()
, который возвращает int .
перемещение в допустимую строку и для корректности перемещенияназад к строке, курсор был ранее расположен на.
Таким образом, я считаю, что вам будет нужно следующее: -
public static Object getSQLValue(Cursor c, String columnName) {
Log.d("CURSORCOUNT","Cursor has a size of " + String.valueOf(c.getCount())); //<<<<<<<<<< for demo //TODO remove me
Object rv = null;
int rowcount = c.getCount();
if (rowcount < 1) {
return rv;
}
int index = getColumnIndex(c, columnName);
int pos = c.getPosition();
boolean moveback = false;
if (pos < 0 || pos >= rowcount) {
c.moveToFirst();
moveback = true;
}
if (index > -1) {
switch (c.getType(index)) {
case Cursor.FIELD_TYPE_BLOB:
rv = c.getBlob(index);
break;
case Cursor.FIELD_TYPE_FLOAT:
rv = c.getFloat(index);
break;
case Cursor.FIELD_TYPE_STRING:
rv = c.getString(index);
break;
case Cursor.FIELD_TYPE_INTEGER:
rv = c.getInt(index);
break;
}
}
if(moveback) c.moveToPosition(pos);
return rv;
}
- Примечаниевышеупомянутое было исправлено, чтобы удовлетворить сохранению положения.Если курсор был перемещен в строку (см. Курсор c3 в тестировании), то эта позиция строки будет использоваться для извлечения данных / типа.Однако, если курсор находится перед первым или после первого ряда, то выполняется перемещение в первый ряд, и позиция восстанавливается до возврата.
Проверка
Предполагая, что БД с таблицей и метод getRows , который имеет логический параметр - если false, то все строки в таблице извлекаются через Курсор - если true, тогда возвращается пустой Курсор
Для проверки используется следующее: -
public class MainActivity extends AppCompatActivity {
DBHelper mDBHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHlpr = new DBHelper(this); //<<<<<<<<<< The Database Helper
mDBHlpr.getWritableDatabase().delete(DBHelper.TBL_MYTABLE,null,null); //<<<<<<<<<< empty table
// Add some testing data
mDBHlpr.insert("2019-03-25T19:19:39.664Z");
mDBHlpr.insert("\"2019-03-25T19:19:39.664Z\"");
// Get a populated cursor (c1) and and empty cursor (c2)
Cursor c1 = mDBHlpr.getRows(false); //<<<<<<<<<< populated
Cursor c2 = mDBHlpr.getRows(true); //<<<<<<<<< empty
Cursor c3 = mDBHlpr.getRows(false); //<<<<<<<<<< populated for position preservation example
c3.moveToPosition(1); //<<<<<<<<<< moved to 2nd row
// Try with a non-existant column for the populated cursor
logit(DBHelper.getSQLValue(c1,"NOTACOLUMN"),"TEST1 - NOT A COLUMN");
// Try with a valid column for the populated cursor
logit(DBHelper.getSQLValue(c1,DBHelper.COL_MYTABLE_MYSTRING),"TEST2 - VALID COLUMN");
// Try with a non-existant column for the empty cursor
logit(DBHelper.getSQLValue(c2,"NOTACOLUMN"),"TEST3 - NOT A COLUMN - EMPTY CURSOR");
// Try with a valid column for the empty cursor
logit(DBHelper.getSQLValue(c2,DBHelper.COL_MYTABLE_MYSTRING),"TEST4 - VALID COLUMN - EMPTY CURSOR");
//PRESERVATION OF POSITION EXAMPLE
// Try with a valid column for the populated cursor
logit(DBHelper.getSQLValue(c3,DBHelper.COL_MYTABLE_MYSTRING),"TEST2 - VALID COLUMN");
Log.d("PRESERVED_POS", "Position is " + String.valueOf(c3.getPosition()));
}
private void logit(Object o,String tag) {
String msg = "OBJECT IS NULL!!!!";
if (o != null) {
msg = "OBJECT IS " + o.toString();
}
Log.d(tag,msg);
}
}
Результат
03-23 13:19:36.175 20570-20570/? D/CURSORCOUNT: Cursor has a size of 2
03-23 13:19:36.176 20570-20570/? D/TEST1 - NOT A COLUMN: OBJECT IS NULL!!!!
03-23 13:19:36.176 20570-20570/? D/CURSORCOUNT: Cursor has a size of 2
03-23 13:19:36.176 20570-20570/? D/TEST2 - VALID COLUMN: OBJECT IS 2019-03-25T19:19:39.664Z
03-23 13:19:36.176 20570-20570/? D/CURSORCOUNT: Cursor has a size of 0
03-23 13:19:36.176 20570-20570/? D/TEST3 - NOT A COLUMN - EMPTY CURSOR: OBJECT IS NULL!!!!
03-23 13:19:36.176 20570-20570/? D/CURSORCOUNT: Cursor has a size of 0
03-23 13:19:36.176 20570-20570/? D/TEST4 - VALID COLUMN - EMPTY CURSOR: OBJECT IS NULL!!!!
03-23 13:19:36.176 20570-20570/? D/CURSORCOUNT: Cursor has a size of 2
03-23 13:19:36.176 20570-20570/? D/TEST2 - VALID COLUMN: OBJECT IS "2019-03-25T19:19:39.664Z"
03-23 13:19:36.176 20570-20570/? D/PRESERVED_POS: Position is 1
Важно, что не существует исключения, где было бы исключение, и какв последних двух строках позиция Курсора сохраняется.
Обратите внимание , что каждая отдельная комбинация строки / столбца может иметь свой собственный тип и исключение.столбца rowid или его псевдонима (значение может быть только целым числом для такого столбца ), любой тип значения может быть сохранен в любом типе столбца.
Примечание getInt может не получить все значения правильно, так как тип столбца INTEGER может хранить 64-битные значения со знаком, поэтому в некоторых случаях getLong может потребоваться для получения допустимых значений.Точно так же для предотвращения потери точности может потребоваться getDouble вместо getFloat .