Android - SQLite Cursor getColumnIndex () чувствителен к регистру? - PullRequest
9 голосов
/ 27 января 2012

Во время работы с SQLiteCursor в Android я узнал, что getColumnIndex () ведет себя с учетом регистра, например:

Пример:

Column Name in DB was: Rules
cursor.getColumnIndex("Rules")  //workes fine
cursor.getColumnIndex("rules")  //throws error, see the error detail

В документации об этом ничего не сказано, подробности см. Здесь .

LogCat говорит:

java.lang.IllegalStateException: Не удалось прочитать строку 0, столбец -1 из CursorWindow.Убедитесь, что курсор инициализирован правильно, прежде чем получить доступ к данным из него

Меня смущает такое поведение SQLiteCursor, кто-то может мне помочь, что это правда ИЛИ я делаю что-то не так?Я могу предоставить код, если требуется.

Спасибо.

Ответы [ 3 ]

4 голосов
/ 07 марта 2012

getColumnIndex () чувствителен к регистру:

Имя столбца в БД было: Правила

cursor.getColumnIndex (" Правила ") // работает нормально

cursor.getColumnIndex (" rules ") // выдает ошибку, см. Подробности ошибки

1 голос
/ 04 апреля 2015

Другим способом было бы запросить у самой базы данных правильное имя, используя PRAGMA table_info, поэтому я написал метод для этого:

public class database {
    private SQLiteDatabase mainDB = null;

    private boolean CreateOrOpenDB() {
        try {
            if (mainDB == null || !mainDB.isOpen()) {
                mainDB = Context.openOrCreateDatabase("mainDB", SQLiteDatabase.CREATE_IF_NECESSARY, null);
            }
        } catch (SQLiteException e) {
            return false;
        }
        return true;
    }

    private String GetTrueColumnName(String TableName, String column) {
        String TrueColName = "";
        if (CreateOrOpenDB()) {
            try {
                Cursor c = mainDB.rawQuery("PRAGMA table_info(" + TableName + ");", null);

                if (c != null) {
                    if (c.moveToFirst()) {
                        do {
                            String dbcolumn = c.getString(c.getColumnIndex("name"));
                            if (column.toLowerCase().equals(dbcolumn.toLowerCase())) {
                                TrueColName = dbcolumn;
                                break;
                            }
                        } while (c.moveToNext());
                    }
                    c.close();
                }
                mainDB.close();
            } catch (Exception e) {
            }
        }
        return TrueColName;
    }
}

тогда все, что вам нужно для вызова:

String CorrectName = GetTrueColumnName(TableName, "RuLeS");

и да, я знаю, что это будет сложно для базы данных. Но работает и стабильно

1 голос
/ 27 января 2012

Лучший и рекомендуемый подход с использованием SQLite состоит в том, что вы объявляете все имена таблиц и имен столбцов static, final и class level .. например:

// write table name
public static final String TABLE_MESSAGE = "messages";
// and column name accordingly
public static final String COLUMN_ID = "_id";
public static final String COLUMN_MESSAGE = "message";

, поэтому выгодаПри таком подходе вам не нужно запоминать написание и регистр и т. д. имен таблиц и столбцов.

при доступе к любой таблице или столбцу вы просто используете эти статические переменные, например:

// TABLE creation sql statement
private static final String TABLE_CREATE = "create table "
            + TABLE_MESSAGE + "( " + COLUMN_ID
            + " integer primary key autoincrement, " + COLUMN_MESSAGE
            + " text not null);";

при запросе:

database.query(TABLE_MESSAGE, new String[]{COLUMN_ID,COLUMN_MESSAGE}, null, null, null, null, null);

или его можно использовать в курсоре

int index = cursor.getColumnIndex(COLUMN_MESSAGE);

, это поможет вам избежать таких конфликтов чувствительности к регистру и орфографических ошибок.:)

...