Когда выполняется 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()
возвращает успешно (не вызывает исключения), предполагается, что база данных создается с запрошенным номером версии. Как следствие, вы не должны пойматьSQLException
s inonCreate()
себя.
onUpgrade()
вызывается только тогда, когда файл базы данных существует, но сохраненный номер версии ниже, чем запрошено в конструкторе. ЭлементonUpgrade()
должны обновите схему таблицы до требуемой версии.при изменении схемы таблицы в код (
onCreate()
), вы должны убедиться, что база данных обновляется. Два основных подхода:
Удалите старый файл базы данных, чтобы
onCreate()
снова запустить. Это часто предпочтительнее во время разработки, когда у вас есть контроль над установленными версиями и потеря данных не является проблемой. Некоторые способы удаления базы данных файл:
удалить приложение. Используйте диспетчер приложений или
adb uninstall your.package.name
от shell.Очистить данные приложения. Используйте диспетчер приложений.
увеличьте версию базы данных так, чтобы
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-й param), платформа проверяет, существует ли база данных или нет, и если база данных существует, она получает информацию о версии из заголовка файла базы данных и запускает правильный вызов назадкак уже объяснялось в предыдущем ответе, если база данных с именем не существует, она запускает
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
до3
а потом4
если старая версия
3
и новая версия4
, это будет просто запустить логику обновления для3
до4
onCreate()
когда мы создаем базу данных в первый раз (т. е. база данных не существует)
onCreate()
создать базу данных с версией, которая передается вSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
onCreate()
метод создает таблицы, которые вы определили, и выполняет любой другой написанный вами код. Однако этот метод будет вызван только в том случае, если файл SQLite отсутствует в каталоге данных вашего приложения (/data/data/your.apps.classpath/databases
).этот метод не будет вызван, если вы изменили свой код и перезапустили его в эмуляторе. Если вы хотите
onCreate()
для запуска вам нужно использовать adb для удаления файла базы данных SQLite.
onUpgrade()
SQLiteOpenHelper
должен вызвать супер конструктор.- The
onUpgrade()
метод будет вызываться только тогда, когда целое число версии больше, чем текущая версия, запущенная в приложение.- если вы хотите
onUpgrade()
метод, который будет вызван, вам нужно увеличить номер версии в коде.
может быть, я слишком поздно, но я хотел бы поделиться своим коротким и сладким ответом. Пожалуйста, проверьте ответ для той же проблемы. Это, безусловно, поможет вам. Нет более глубоких спецификаций.
если вы уверены в синтаксисе для создания таблицы, чем это может произойти, когда вы добавляете новый столбец в той же таблице, для этого...
1) Удалите с вашего устройства и запустите его снова.
или
2) Установка -> приложения -> ClearData
или
3) изменить
DATABASE_VERSION
в вашем классе " DatabaseHandler "(если вы добавили новый столбец, чем он будет обновляться автоматически)public DatabaseHandler(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); }
или
4) изменить
DATABASE_NAME
в вашем классе "DatabaseHandler" (я столкнулся с той же проблемой. Но я преуспеваю, меняяDATABASE_NAME
.)
что следует помнить при расширении
SQLiteOpenHelper
super(context, DBName, null, DBversion);
- это должно быть вызвано в первой строке конструктора- переопределить
onCreate
иonUpgrade
(Если требуется)onCreate
будет вызываться только тогда, когдаgetWritableDatabase()
илиgetReadableDatabase()
выполняется. И это будет вызываться только один раз, когда aDBName
указанный на первом шаге недоступен. Вы можете добавить запрос создать таблицу наonCreate
метод- всякий раз, когда вы хотите добавить новую таблицу просто изменить
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); } }
Примечание: Если вы хотите создать другую таблицу или добавить столбцы или нет такой таблицы, просто увеличьте версию
Если вы забыли указать строку " имя "в качестве второго аргумента конструктора, он создает базу данных" в памяти", которая стирается при закрытии приложения.
onCreate вызывается впервые, когда требуется создание таблиц. Нам нужно переопределить этот метод, где мы пишем сценарий для создания таблицы, которая выполняется SQLiteDatabase. метод execSQL. После выполнения в первом развертывании этот метод не будет вызываться вперед.
onUpgrade Этот метод вызывается при обновлении базы данных. Предположим, что при первом развертывании версия базы данных была 1 и в второе развертывание произошло изменение структуры базы данных, например добавление дополнительного столбца в таблицу. Предположим, что версия базы данных теперь равна 2.