Когда выполняется SQLiteOpenHelper onCreate() / onUpgrade ()?

Я создал свои таблицы в моем SQLiteOpenHelper onCreate() но получать

SQLiteException: no such table

или

SQLiteException: no such column

ошибки. Почему?

Примечание:

(это объединенное резюме десятков подобных вопросов каждую неделю. Попытка предоставить "канонический" вопрос/ответ сообщества wiki здесь, чтобы все эти вопросы могли быть направлены на хорошую ссылку.)

13 ответов


SQLiteOpenHelper onCreate() и onUpgrade() обратные вызовы вызываются, когда база данных фактически открыта, например, вызовом getWritableDatabase(). База данных не открывается при создании самого вспомогательного объекта базы данных.

SQLiteOpenHelper версии файлов базы данных. Номер версии -int аргумент передан конструктор. В файле базы данных, номер версии хранится в PRAGMA user_version.

onCreate() запускается только тогда, когда файл базы данных не существует и только что был создан. Если onCreate() возвращает успешно (не создает исключения), предполагается, что база данных будет создана с запрошенным номером версии. Как намек, вы не должны поймать SQLExceptions в onCreate() себя.

onUpgrade() вызывается только тогда, когда файл базы данных существует, но сохраненный номер версии ниже, чем запрошено в конструкторе. The onUpgrade() должны обновите схему таблицы до запрошенной версии.

при изменении схемы таблицы в код (onCreate()), вы должны убедиться, что база данных обновляется. Два основных подхода:

  1. Удалите старый файл базы данных, чтобы onCreate() снова запустить. Это часто предпочтительнее во время разработки, когда у вас есть контроль над установленными версиями и потеря данных не является проблемой. Некоторые способы удаления базы данных файл:

    • удалить приложение. Используйте диспетчер приложений или adb uninstall your.package.name от shell.

    • Очистить данные приложения. Используйте диспетчер приложений.

  2. увеличьте версию базы данных так, чтобы onUpgrade() вызывается. Это немного сложнее, поскольку требуется больше кода.

    • для обновления схемы времени разработки, где потеря данных не является проблемой, вы можете просто использовать execSQL("DROP TABLE IF EXISTS <tablename>") in, чтобы удалить существующие таблицы и вызвать onCreate() для воссоздания базы данных.

    • для выпущенных версий необходимо реализовать миграцию данных в onUpgrade() чтобы ваши пользователи не теряли свои данные.


для дальнейшего добавления недостающих точек здесь, в соответствии с запросом Jaskey

версия базы данных хранится в SQLite файл базы данных.

catch-это конструктор

SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

поэтому, когда вспомогательный конструктор базы данных вызывается с помощью name (2-й парам), платформа проверяет, существует ли база данных или нет, и если база данных существует, она получает информацию о версии из заголовка файла базы данных и запускает правильный вызов назад!--26-->

как уже объяснялось в предыдущем ответе, если база данных с именем не существует, она запускает onCreate.

ниже объяснение объясняет onUpgrade случае с примером.

скажем, ваша первая версия приложения имела DatabaseHelper (протяженностью SQLiteOpenHelper) с конструктором, передающим версию как 1 и затем вы предоставили обновленное приложение с новым исходным кодом, версия которого прошла как 2, затем автоматически, когда DatabaseHelper is построенный, триггеры платформы onUpgrade, увидев, что файл уже существует, но версия ниже чем текущая версия, который вы прошли.

теперь скажите, что вы планируете дать третью версию приложения с версией db как 3 (версия БД увеличивается только при изменении схемы базы данных). В таких инкрементных обновлениях вы должны писать логику обновления из каждой версии постепенно для лучшего поддерживаемого кода

пример псевдо код ниже:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  switch(oldVersion) {
    case 1:
       //upgrade logic from version 1 to 2
    case 2:
       //upgrade logic from version 2 to 3
    case 3:
       //upgrade logic from version 3 to 4
       break;
    default:
       throw new IllegalStateException(
                "onUpgrade() with unknown oldVersion " + oldVersion);
  }
}

обратите внимание на недостающие break заявление в случае 1 и 2. Вот что я имею в виду под инкрементным обновлением.

скажите, если старая версия 2 и новая версия 4, затем логика обновит базу данных с 2 to 3 а потом 4

если старая версия 3 и новая версия 4, он будет просто запускать логику обновления для 3 to 4


onCreate()

  1. когда мы создаем базу данных в первый раз (i.E база данных не существует)onCreate() создать базу данных с версией, которая передается в SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

  2. onCreate() метод создает таблицы, которые вы определили, и выполняет любой другой написанный вами код. Однако этот метод будет вызываться только в том случае, если файл SQLite отсутствует в каталоге данных вашего приложения (/data/data/your.apps.classpath/databases).

  3. этот метод не будет вызываться, если вы изменили свой код и перезапустили его в эмуляторе. Если вы хотите onCreate() для запуска вам нужно использовать adb для удаления файла базы данных SQLite.

onUpgrade()

  1. SQLiteOpenHelper должен вызвать супер конструктор.
  2. на onUpgrade() метод будет вызываться только тогда, когда целое число версии больше текущей версии, запущенной в приложение.
  3. если вы хотите onUpgrade() метод, который будет вызван, вам нужно увеличить номер версии в вашем коде.

может быть, я слишком поздно, но я хотел бы поделиться своим коротким и сладким ответом. Пожалуйста, проверьте ответ для той же проблемы. Это определенно поможет вам. Нет более глубоких спецификаций.

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

1) Удалите с устройства и запустите его снова.

или

2) Установка - >app - > ClearData

или

3) изменить DATABASE_VERSION в вашем классе "DatabaseHandler" (если вы добавили новый столбец, он будет обновляться автоматически)

public DatabaseHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

или

4) изменить DATABASE_NAME в вашем классе" DatabaseHandler " (я столкнулся с той же проблемой. Но я преуспеваю, меняясь DATABASE_NAME.)


что следует помнить при расширении SQLiteOpenHelper

  1. super(context, DBName, null, DBversion); - Это должно быть вызвано первой строке конструктора
  2. переопределить onCreate и onUpgrade (Если требуется)
  3. onCreate будет вызываться только тогда, когда getWritableDatabase() или getReadableDatabase() выполняется. И это будет вызываться только один раз, когда DBName указанный на первом шаге недоступен. Вы можете добавить запрос create table на onCreate метод
  4. всякий раз, когда вы хотите добавить новую таблицу просто изменить DBversion и сделайте запросы в onUpgrade таблицы или просто установить приложение.

удалить приложение из эмулятора или устройства. Запустите приложение еще раз. (OnCreate () не выполняется, когда база данных уже существует)


такая таблица не найдена в основном, когда вы не открыли SQLiteOpenHelper класс getwritabledata() и перед этим вам также нужно вызвать конструктор make с databasename & version. И OnUpgrade вызывается всякий раз, когда есть значение обновления в номере версии, приведенном в SQLiteOpenHelper класса.

Ниже приведен фрагмент кода (такой столбец не найден из-за орфографии в имени столбца):

public class database_db {
    entry_data endb;
    String file_name="Record.db";
    SQLiteDatabase sq;
    public database_db(Context c)
    {
        endb=new entry_data(c, file_name, null, 8);
    }
    public database_db open()
    {
        sq=endb.getWritableDatabase();
        return this;
    }
    public Cursor getdata(String table)
    {
        return sq.query(table, null, null, null, null, null, null);
    }
    public long insert_data(String table,ContentValues value)
    {
        return sq.insert(table, null, value);
    }
    public void close()
    {
        sq.close();
    }
    public void delete(String table)
    {
        sq.delete(table,null,null);
    }
}
class entry_data extends SQLiteOpenHelper
{

    public entry_data(Context context, String name, SQLiteDatabase.CursorFactory factory,
                      int version) {
        super(context, name, factory, version);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onCreate(SQLiteDatabase sqdb) {
        // TODO Auto-generated method stub

        sqdb.execSQL("CREATE TABLE IF NOT EXISTS 'YOUR_TABLE_NAME'(Column_1 text not null,Column_2 text not null);");

    }

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
          onCreate(db);
    }

}

вы можете создать базу данных и таблицы, как

public class DbHelper extends SQLiteOpenHelper {
private static final String DBNAME = "testdatbase.db";
private static final int VERSION = 1;

public DbHelper(Context context) {
    super(context, DBNAME, null, VERSION);
    // TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub
    db.execSQL("create table BookDb(id integer primary key autoincrement,BookName text,Author text,IssuedOn text,DueDate text,Fine text,Totalfine text");

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS BookDb");
    onCreate(db);
  }
}

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


имя базы данных должно заканчиваться .дБ также ваши строки запроса должны иметь Терминатор (;)


Если вы забыли указать строку " name "в качестве второго аргумента конструктору, он создает базу данных" In-memory", которая стирается при закрытии приложения.


onCreate вызывается впервые при необходимости создания таблиц. Нам нужно переопределить этот метод, где мы пишем сценарий для создания таблицы, который выполняется SQLiteDatabase. метод execSQL. После выполнения в первом развертывании этот метод не будет вызываться далее.

onUpgrade Этот метод вызывается при обновлении базы данных. Предположим, что для первого развертывания версия базы данных была 1 и в второе развертывание произошло изменение структуры базы данных, например добавление дополнительного столбца в таблицу. Предположим, что версия базы данных теперь равна 2.


перепроверьте свой запрос в классе Ur DatabaseHandler / DatabaseManager (который вы когда-либо брали)


метод Sqliteopenhelper имеет методы create и upgrade,create используется, когда любая таблица впервые создается, и метод обновления будет вызываться каждый раз, когда изменяется номер столбца таблицы.