Не удалось прочитать строку 0, столбец -1

Я пытаюсь скопировать базу данных, которую я создал с менеджером SQLite, в котором я сделал:

CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US') 

а также

 INSERT INTO "android_metadata" VALUES ('en_US') 

И я назвал все мои основные ключи _id . Моя база данных копируется (в первом запуске в логарифме) есть красные сообщения; После этого он только дает ошибку, когда я его запрашиваю.

Основная деятельность

 public class MainActivity extends Activity { String CNAME=" ques",TABLE_NAME=" JAVAQ"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Setupdb dbobj=new Setupdb(this); try { //dbobj.close(); dbobj.createDataBase(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } dbobj.openDataBase(); dbobj.close(); try{ SQLiteDatabase sqdb=dbobj.getReadableDatabase(); Cursor c = sqdb.query(TABLE_NAME, new String[] { CNAME }, null, null, null, null, null); while (c.moveToNext()) { String name = c.getString(c.getColumnIndex(CNAME)); Log.i("LOG_TAG", " HAS NAME " + name); }} catch(Exception e){ Log.e("err", e.toString()); } }} 

Setupdb

 public class Setupdb extends SQLiteOpenHelper { private static String DB_PATH = ""; private static final String DB_NAME = "camprep.sqlite"; private SQLiteDatabase myDataBase; private final Context myContext; private static Setupdb mDBConnection; public Setupdb(Context context) { super(context, DB_NAME, null, 3); this.myContext=context; DB_PATH="/data/data/" + context.getApplicationContext().getPackageName() + "/databases/"; Log.e(DB_NAME, DB_PATH); } public static synchronized Setupdb getDBAdapterInstance(Context context) { if (mDBConnection == null) { mDBConnection = new Setupdb(context); } return mDBConnection; } public void createDataBase() throws IOException { boolean dbExist = checkDataBase(); if (dbExist) { Log.e("db","exist"); // do nothing - database already exist } else { // By calling following method // 1) an empty database will be created into the default system path of your application // 2) than we overwrite that database with our database. this.getReadableDatabase(); try { Log.e("calling", "copy"); copyDataBase(); } catch (IOException e) { throw new Error("Error copying database"); } } } private boolean checkDataBase() { SQLiteDatabase checkDB = null; try { String myPath = DB_PATH + DB_NAME; checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); } catch (SQLiteException e) { // database does't exist yet. } if (checkDB != null) { checkDB.close(); } return checkDB != null ? true : false; } private void copyDataBase() throws IOException { // Open your local db as the input stream InputStream myInput = myContext.getAssets().open(DB_NAME); // Path to the just created empty db String outFileName = DB_PATH + DB_NAME; // Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(outFileName); // transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } // Close the streams myOutput.flush(); myOutput.close(); myInput.close(); } public void openDataBase() throws SQLException { String myPath = DB_PATH + DB_NAME; myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); } public synchronized void close() { if (myDataBase != null) myDataBase.close(); super.close(); } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } 

Трассировки стека

  08-31 20:17:05.320: I/dalvikvm(9457): threadid=3: reacting to signal 3 08-31 20:17:05.370: I/dalvikvm(9457): Wrote stack traces to '/data/anr/traces.txt' 08-31 20:17:05.451: E/camprep.sqlite(9457): /data/data/com.example.mydataexplosion/databases/ 08-31 20:17:05.490: E/db(9457): exist 08-31 20:17:05.521: E/CursorWindow(9457): Failed to read row 0, column -1 from a CursorWindow which has 11 rows, 1 columns. 08-31 20:17:05.521: E/err(9457): java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 08-31 20:17:05.650: D/gralloc_goldfish(9457): Emulator without GPU emulation detected. 08-31 20:17:05.650: I/dalvikvm(9457): threadid=3: reacting to signal 3 08-31 20:17:05.670: I/dalvikvm(9457): Wrote stack traces to '/data/anr/traces.txt' 

Если ты видишь

 failed to read row 0,column -1 

Это означает, что вы пытаетесь прочитать из столбца, который не существует.

Если он не может найти имя столбца, которое вы указали, Cursor.getColumnIndex() возвращает -1 и, следовательно, является недопустимым.

Для этого есть две причины:

  1. Столбец не существует.
  2. Имя столбца неверно. (Так не существует).

Примечание: имя столбца CASE SENSITIVE при использовании getColumnIndex()


В вашем сценарии:

  c.getString(c.getColumnIndex(CNAME)); 

Убедитесь, что переменная CNAME написана правильно и что столбец этого имени существует.

 String CNAME=" ques" 

Должно быть, что это дополнительное ведущее белое пространство, например.

Прежде чем вы начнете считывать последовательные значения с помощью c.moveToNext() , установите курсор в начальную позицию, то есть начало вашей базы данных.

c.moveToFirst()

А затем начать читать форму.

Можете решить вашу проблему.

Ошибка заключалась в использовании умляутов ü, ö, ä в именах столбцов базы данных.

Хотя вы можете получить контент, перейдя с методом cursor.movetonext() так часто, пока не переместитесь на нужный номер, это было очень неприятно и запросило кучу кода.

Думаю, это должно решить проблемы для большинства из вас. Я думаю, что ничего, кроме ASCII, неверно – пробелы, точки, минусы и т. Д. Тоже не могут быть использованы.

Вы можете успешно создать базу данных, и вы можете увидеть ее с помощью внешних инструментов sqlite, но андроид всегда будет петь.

Другой сценарий, когда это может произойти:
Вы удаляете строки из курсора, пока курсор все еще используется.

Например, псевдокод, где это может произойти:

 while(cursor.moveToNext()){ readCursor(cursor); deleteRowFromCursor(cursor); } в while(cursor.moveToNext()){ readCursor(cursor); deleteRowFromCursor(cursor); } 

Решение:

Сохранять список строк, которые вы хотите удалить; Создать пакетную инструкцию sql delete; Выполните часть сонга из цикла while (когда вы закончите использовать курсор больше или после его закрытия).

 while(cursor.moveToNext()){ readCursor(cursor); queueRowForDelete(cursor); } deleteQueuedRows(queuedRowsList); в while(cursor.moveToNext()){ readCursor(cursor); queueRowForDelete(cursor); } deleteQueuedRows(queuedRowsList);