Я пытаюсь настроить простую базу данных SQLite в Android, обрабатывая схему через подкласс SQLiteOpenHelper. Однако, когда я запрашиваю свои таблицы, столбцы, которые, как мне кажется, я вставил, никогда не присутствуют.

А именно, в методе SQLiteOpenHelper onCreate(SQLiteDatabase db) я использую db.execSQL() для запуска команд CREATE TABLE, затем пробовал как db.execSQL, так и db.insert() запускать команды INSERT для таблиц, которые я только что созданный. Кажется, это работает нормально, но когда я пытаюсь запросить их, я всегда получаю 0 строк (для отладки выполняемые мной запросы простые SELECT * FROM table и проверка курсора getCount()).

Кто-нибудь сталкивался с чем-то подобным раньше? Эти команды, похоже, запускаются в командной строке sqlite3. Есть ли у меня ошибки, которые мне не хватает (например, INSERTS должны / не должны завершаться точкой с запятой или какая-то проблема, связанная с несколькими таблицами)? Я приложил часть кода ниже.

Спасибо за ваше время и дайте мне знать, если я смогу уточнить детали.


@Override
public void onCreate(SQLiteDatabase db)
{
    db.execSQL("CREATE TABLE "+ LEVEL_TABLE +" (" + 
               "  "+ _ID +" INTEGER PRIMARY KEY AUTOINCREMENT," +
               "  level TEXT NOT NULL,"+
               "  rows INTEGER NOT NULL,"+
               "  cols INTEGER NOT NULL);");

    db.execSQL("CREATE TABLE "+ DYNAMICS_TABLE +" (" + 
               "  level_id INTEGER NOT NULL," +
               "  row INTEGER NOT NULL,"+
               "  col INTEGER NOT NULL,"+
               "  type INTEGER NOT NULL);");

    db.execSQL("CREATE TABLE "+ SCORE_TABLE +" (" + 
               "  level_id INTEGER NOT NULL," +
               "  score INTEGER NOT NULL,"+
               "  date_achieved DATE NOT NULL,"+
               "  name TEXT NOT NULL);");
    this.enterFirstLevel(db);
}

И образец кода вставки, который я сейчас использую, который вызывается в enterFirstLevel() (некоторые значения жестко запрограммированы только для его запуска ...):

private void insertDynamic(SQLiteDatabase db, int row, int col, int type)
{
    ContentValues values = new ContentValues();

    values.put("level_id", "1");
    values.put("row", Integer.toString(row));
    values.put("col", Integer.toString(col));
    values.put("type", Integer.toString(type));

    db.insertOrThrow(DYNAMICS_TABLE, "col", values);
}

Наконец, код запроса выглядит так:

private Cursor fetchLevelDynamics(int id)
{
    SQLiteDatabase db = this.leveldata.getReadableDatabase();
    try {
        String fetchQuery = "SELECT * FROM " + DYNAMICS_TABLE;
        String[] queryArgs = new String[0];         
        Cursor cursor = db.rawQuery(fetchQuery, queryArgs);

        Activity activity = (Activity) this.context;
        activity.startManagingCursor(cursor);
        return cursor;
    }
    finally {
        db.close();
    }
}
2
pablo.meier 5 Апр 2010 в 09:30

3 ответа

Лучший ответ

Мне это кажется вполне нормальным.

Для устранения неполадок я бы предложил добавить хотя бы один столбец в ваш queryArgs. Я не уверен в эффекте отправки пустого списка. Возможно, это приведет к тому, что строки не будут возвращены, даже если есть результаты.

Нет необходимости преобразовывать ваши целочисленные значения в строки в ContentValues. Попробуйте заменить values.put("row", Integer.toString(row)); только на values.put("row", row);. Вероятно, это не является причиной вашей проблемы, поскольку это вызвало бы исключение, если бы возражало против строк.

Я никогда не использовал SQLiteDatabase.rawQuery (), может попробовать более часто используемый .query ()?

Я не вижу, что ваш код делает с «курсором», возвращаемым fetchLevelDynamics (), поэтому я не могу исключить там логические ошибки.

0
Jim Blackler 5 Апр 2010 в 09:55
Хотя технически это не было ответом (я нашел его и написал как отдельный ответ на вопрос), мне понравились советы по отладке, я хотел, чтобы вопрос был отмечен как ответ, и чтобы дать вам очки репутации. Спасибо за помощь ^ _ ^
 – 
pablo.meier
21 Апр 2010 в 22:35

Разобрался, было несколько разных вещей. Прежде всего, это код запроса: Cursor может перемещаться только по открытой базе данных. Таким образом, приведенный выше метод запроса вернет Cursor, а затем закроет базу данных в блоке finally.

Курсор не будет работать должным образом, но не выдаст ошибку при работе с закрытой базой данных. Он просто скажет, что вернул 0 строк (поэтому я подумал, что ошибка была в коде INSERT).

Кроме того, я забыл кое-что о SQL, а именно, что row и col - не лучшие имена для полей таблицы, и я смог избавиться от нескольких ошибок, переименовав их в row_num и col_num

2
pablo.meier 21 Апр 2010 в 22:33

Попробуйте использовать null для второго параметра в

db.insertOrThrow(DYNAMICS_TABLE, "col", values);
0
Randy Sugianto 'Yuku' 5 Апр 2010 в 09:55