Каква е грешката в този курсор, създаден за база данни?

Създавам SQLite база данни в android. Но има някаква грешка, която се появява всеки път, когато извикам метода "displayDatabase()".

Моля, помогнете!!

Ето метода displayDatabase():

public void displayDatabase() {

    DataDbHelper mDbHelper = new DataDbHelper(this);

    SQLiteDatabase db = mDbHelper.getReadableDatabase();

    String[] projection = {DataContract.DataEntry.COLUMN_PROJECT_NAME,
            DataContract.DataEntry.COLUMN_HEAD,
            DataContract.DataEntry.COLUMN_CITY,
            DataContract.DataEntry.COLUMN_COST};
    Cursor c = db.query(DataContract.DataEntry.TABLE_NAME,
            projection,
            null,
            null,
            null,
            null,
            null);
    TextView textView = (TextView) findViewById(R.id.textview);

    try {
        //textView.setText("The database contains - " + c.getColumnCount() + "Columns containing data");

        textView.setText("Hello Welcome\n");

        textView.append("-" + DataContract.DataEntry._ID
                + "---" + DataContract.DataEntry.COLUMN_PROJECT_NAME
                + "---" + DataContract.DataEntry.COLUMN_HEAD
                + "---" + DataContract.DataEntry.COLUMN_CITY
                + "---" + DataContract.DataEntry.COLUMN_COST + "\n");


        int currentId = c.getColumnIndex(DataContract.DataEntry._ID);
        int projectNameId = c.getColumnIndex(DataContract.DataEntry.COLUMN_PROJECT_NAME);
        int headId = c.getColumnIndex(DataContract.DataEntry.COLUMN_HEAD);
        int cityId = c.getColumnIndex(DataContract.DataEntry.COLUMN_CITY);
        int costId = c.getColumnIndex(DataContract.DataEntry.COLUMN_COST);


        while (c.moveToNext()) {
            int id = c.getInt(currentId);
            String projectName = c.getString(projectNameId);
            String head = c.getString(headId);
            String city = c.getString(cityId);
            String cost = c.getString(costId);

            textView.append("-" + id
                    + "---" + projectName
                    + "---" + head
                    + "---" + city
                    + "---" + cost);


        }


    } finally {
        c.close();
    }
}

И ето грешката, която се появява в logcat:

CursorWindow: Неуспешно четене на ред 0, колона -1 от CursorWindow, който има 11 реда, 4 колони. 03-15 10:00:58.359 6348-6348/? E/AndroidRuntime: ФАТАЛНО ИЗКЛЮЧЕНИЕ: основен процес: com.example.student.sampledatabase, PID: 6348 java.lang.IllegalStateException: Не може да се прочете ред 0, колона -1 от CursorWindow. Уверете се, че курсорът е инициализиран правилно, преди да получите достъп до данни от него.


person Akshat Chaturvedi    schedule 15.03.2019    source източник
comment
опитвате се да получите индекса на колона, която не сте включили в командата Select   -  person Vladyslav Matviienko    schedule 15.03.2019
comment
Освен това, като наистина по-добра алтернатива на директното използване на SQLite, опитайте вместо това Room Persistence Library от Google (въведена през 2017 г.). Прочетете тук: developer.android.com/topic/libraries/architecture/room и гледайте това за бърза идея: youtube.com/watch?v=SKWh4ckvFPM стая намалява целия шаблонен код на SQLite и всяка възможност за грешки, като го генерира автоматично за вас. Можете директно да картографирате вашите класове обекти на данни с базата данни.   -  person MD Naseem Ashraf    schedule 15.03.2019


Отговори (2)


Добавете тази колона, DataContract.DataEntry._ID, към вашата проекция.

person PPartisan    schedule 15.03.2019

Причината за грешката

Причината за неуспеха е, че се прави опит да се получи колона с отместване -1, което никога няма да съществува, тъй като отместванията могат да бъдат от 0 до броя на колоните в курсора минус 1.

Причината, поради която се използва -1, е, че това е стойността, върната от метода Cursor getColumnIndex, когато името на колоната, предадено на метода, не съществува в курсора.

Причината, поради която получавате -1, е, че не сте включили колоната, чието име е според DataContract.DataEntry._ID, разрешено в курсора, така че редът: -

int currentId = c.getColumnIndex(DataContract.DataEntry._ID);

води до това, че currentId е -1

Следователно горната грешка, когато се изпълни следният ред: -

int id = c.getInt(currentId);

Корекцията

Една корекция би била да се посочи null вместо projection, това ще доведе до извличане на всички колони на таблицата и е еквивалентно на използването на SELECT * FROM .......

напр. като се използва :-

Cursor c = db.query(DataContract.DataEntry.TABLE_NAME,
        null,
        null,
        null,
        null,
        null,
        null);

Друго решение би било да промените: -

String[] projection = {DataContract.DataEntry.COLUMN_PROJECT_NAME,
        DataContract.DataEntry.COLUMN_HEAD,
        DataContract.DataEntry.COLUMN_CITY,
        DataContract.DataEntry.COLUMN_COST};

вместо това да бъде:-

String[] projection = {DataContract.DataEntry._ID,
        DataContract.DataEntry.COLUMN_PROJECT_NAME,
        DataContract.DataEntry.COLUMN_HEAD,
        DataContract.DataEntry.COLUMN_CITY,
        DataContract.DataEntry.COLUMN_COST};

Така колоната ще бъде включена в курсора и отместването ще бъде отместването на тази колона (0 в случая по-горе, тъй като това е първата колона в резултата).

person MikeT    schedule 15.03.2019