Android SQLiteOpenHelper onCreate() / onUpgrade() 何时运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21881992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When is SQLiteOpenHelper onCreate() / onUpgrade() run?
提问by laalto
I have created my tables in my SQLiteOpenHelper
onCreate()
but receive
我已经在我的表中创建了我的表,SQLiteOpenHelper
onCreate()
但收到
SQLiteException: no such table
or
或者
SQLiteException: no such column
errors. Why?
错误。为什么?
NOTE:
(This is the amalgamated summary of tens of similar questions every week. Attempting to provide a "canonical" community wiki question/answer here so that all those questions can be directed to a good reference.)
笔记:
(这是每周数十个类似问题的合并摘要。尝试在此处提供“规范”社区 wiki 问题/答案,以便所有这些问题都可以作为很好的参考。)
回答by laalto
SQLiteOpenHelper
onCreate()
and onUpgrade()
callbacks are invoked when the database is actually opened, for example by a call to getWritableDatabase()
. The database is not opened when the database helper object itself is created.
SQLiteOpenHelper
onCreate()
并且onUpgrade()
在实际打开数据库时调用回调,例如通过调用getWritableDatabase()
. 创建数据库助手对象本身时,不会打开数据库。
SQLiteOpenHelper
versions the database files. The version number is the int
argument passed to the constructor. In the database file, the version number is stored in PRAGMA user_version
.
SQLiteOpenHelper
版本数据库文件。版本号是int
传递给构造函数的参数。在数据库文件中,版本号存储在PRAGMA user_version
.
onCreate()
is only run when the database file did not exist and was just created. If onCreate()
returns successfully (doesn't throw an exception), the database is assumed to be created with the requested version number. As an implication, you should not catch SQLException
s in onCreate()
yourself.
onCreate()
仅在数据库文件不存在且刚刚创建时运行。如果onCreate()
成功返回(不抛出异常),则假定数据库是使用请求的版本号创建的。作为暗示,您不应该SQLException
在onCreate()
自己身上捕获s 。
onUpgrade()
is only called when the database file exists but the stored version number is lower than requested in the constructor. The onUpgrade()
should update the table schema to the requested version.
onUpgrade()
仅当数据库文件存在但存储的版本号低于构造函数中请求的版本号时才调用。本onUpgrade()
应更新表架构所需的版本。
When changing the table schema in code (onCreate()
), you should make sure the database is updated. Two main approaches:
在代码 ( onCreate()
) 中更改表架构时,应确保数据库已更新。两种主要方法:
Delete the old database file so that
onCreate()
is run again. This is often preferred at development time where you have control over the installed versions and data loss is not an issue. Some ways to delete the database file:Uninstall the application. Use the application manager or
adb uninstall your.package.name
from the shell.Clear application data. Use the application manager.
Increment the database version so that
onUpgrade()
is invoked. This is slightly more complicated as more code is needed.For development time schema upgrades where data loss is not an issue, you can just use
execSQL("DROP TABLE IF EXISTS <tablename>")
in to remove your existing tables and callonCreate()
to recreate the database.For released versions, you should implement data migration in
onUpgrade()
so your users don't lose their data.
删除旧的数据库文件,以便
onCreate()
再次运行。这在开发时通常是首选,您可以控制已安装的版本并且数据丢失不是问题。删除数据库文件的一些方法:卸载应用程序。使用应用程序管理器或
adb uninstall your.package.name
从 shell。清除应用程序数据。使用应用程序管理器。
增加数据库版本以便
onUpgrade()
调用。由于需要更多代码,这稍微复杂一些。对于数据丢失不是问题的开发时间架构升级,您可以使用
execSQL("DROP TABLE IF EXISTS <tablename>")
in 删除现有表并调用onCreate()
以重新创建数据库。对于已发布的版本,您应该实现数据迁移,
onUpgrade()
这样您的用户就不会丢失他们的数据。
回答by Aun
To further add missing points here, as per the request by Jaskey
根据 Jaskey 的要求,在此处进一步添加缺失的点
Database version is stored within the SQLite
database file.
数据库版本存储在SQLite
数据库文件中。
catch is the constructor
catch 是构造函数
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
So when the database helper constructor is called with a name
(2nd param), platform checks if the database exists or not and if the database exists, it gets the version information from the database file header and triggers the right call back
因此,当使用name
(第二个参数)调用数据库助手构造函数时,平台检查数据库是否存在,如果数据库存在,它从数据库文件头中获取版本信息并触发正确的回调
As already explained in the older answer, if the database with the name doesn't exists, it triggers onCreate
.
正如旧答案中已经解释的那样,如果具有该名称的数据库不存在,则会触发onCreate
.
Below explanation explains onUpgrade
case with an example.
下面的解释onUpgrade
以一个例子来解释情况。
Say, your first version of application had the DatabaseHelper
(extending SQLiteOpenHelper
) with constructor passing version as 1
and then you provided an upgraded application with the new source code having version passed as 2
, then automatically when the DatabaseHelper
is constructed, platform triggers onUpgrade
by seeing the file already exists, but the version is lower than the current version which you have passed.
说,你的第一个版本的应用程序有DatabaseHelper
(扩展SQLiteOpenHelper
)和构造函数传递版本1
,然后你提供了一个升级的应用程序,新源代码的版本传递为2
,然后在DatabaseHelper
构建时自动,平台onUpgrade
通过看到文件已经存在而触发,但版本低于您通过的当前版本。
Now say you are planing to give a third version of application with db version as 3
(db version is increased only when database schema is to be modified). In such incremental upgrades, you have to write the upgrade logic from each version incrementally for a better maintainable code
现在假设您打算提供具有 db 版本的第三个版本的应用程序3
(仅在修改数据库架构时才会增加 db 版本)。在这种增量升级中,您必须从每个版本增量地编写升级逻辑以获得更好的可维护代码
Example pseudo code below:
示例伪代码如下:
@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);
}
}
Notice the missing break
statement in case 1
and 2
. This is what I mean by incremental upgrade.
注意break
case1
和 中缺少的语句2
。这就是我所说的增量升级的意思。
Say if the old version is 2
and new version is 4
, then the logic will upgrade the database from 2
to 3
and then to 4
假设旧版本是2
新版本4
,那么逻辑将数据库从 升级2
到3
,然后升级到4
If old version is 3
and new version is 4
, it will just run the upgrade logic for 3
to 4
如果旧版本3
和新版本4
,它只是运行升级的逻辑3
来4
回答by jeet parmar
onCreate()
onCreate()
When we create DataBase at a first time (i.e Database is not exists)
onCreate()
create database with version which is passed inSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
onCreate()
method is creating the tables you've defined and executing any other code you've written. However, this method will only be called if the SQLite file is missing in your app's data directory (/data/data/your.apps.classpath/databases
).This method will not be called if you've changed your code and relaunched in the emulator. If you want
onCreate()
to run you need to use adb to delete the SQLite database file.
当我们第一次创建数据库时(即数据库不存在)
onCreate()
用传入的版本创建数据库SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
onCreate()
方法是创建您定义的表并执行您编写的任何其他代码。但是,只有在应用程序的数据目录 (/data/data/your.apps.classpath/databases
) 中缺少 SQLite 文件时,才会调用此方法。如果您更改了代码并在模拟器中重新启动,则不会调用此方法。如果要
onCreate()
运行则需要使用 adb 删除 SQLite 数据库文件。
onUpgrade()
onUpgrade()
SQLiteOpenHelper
should call the super constructor.- The
onUpgrade()
method will only be called when the version integer is larger than the current version running in the app. - If you want the
onUpgrade()
method to be called, you need to increment the version number in your code.
SQLiteOpenHelper
应该调用超级构造函数。onUpgrade()
仅当版本整数大于应用程序中运行的当前版本时才会调用该方法。- 如果要
onUpgrade()
调用该方法,则需要增加代码中的版本号。
回答by Kush
May be I am too late but I would like to share my short and sweet answer. Please check Answerfor a same problem. It will definitely help you. No more deep specifications.
可能是我太晚了,但我想分享我简短而甜蜜的答案。请检查答案以获取相同的问题。它肯定会帮助你。没有更深的规格。
If you are confident about syntax for creating table, than it may happen when you add new column in your same table, for that...
如果您对创建表的语法有信心,那么在同一个表中添加新列时可能会发生这种情况,为此...
1) Uninstall from your device and run it again.
1) 从您的设备中卸载并再次运行。
OR
或者
2) Setting -> app -> ClearData
2) 设置 -> 应用程序 -> ClearData
OR
或者
3)Change DATABASE_VERSION
in your "DatabaseHandler" class (If you have added new column than it will upgrade automatically)
3)更改DATABASE_VERSION
您的“DatabaseHandler”类(如果您添加了新列,它将自动升级)
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
OR
或者
4)Change DATABASE_NAME
in your "DatabaseHandler" class (I faced same problem. But I succeed by changing DATABASE_NAME
.)
4)更改DATABASE_NAME
您的“DatabaseHandler”类(我遇到了同样的问题。但我通过更改成功了DATABASE_NAME
。)
回答by JibinNajeeb
Points to remember when extending SQLiteOpenHelper
延长时要记住的要点 SQLiteOpenHelper
super(context, DBName, null, DBversion);
- This should be invoked first line of constructor- override
onCreate
andonUpgrade
(if needed) onCreate
will be invoked only whengetWritableDatabase()
orgetReadableDatabase()
is executed. And this will only invoked once when aDBName
specified in the first step is not available. You can add create table query ononCreate
method- Whenever you want to add new table just change
DBversion
and do the queries inonUpgrade
table or simply uninstall then install the app.
super(context, DBName, null, DBversion);
- 这应该在构造函数的第一行调用- 覆盖
onCreate
和onUpgrade
(如果需要) onCreate
只会在getWritableDatabase()
或getReadableDatabase()
被执行时被调用。这只会DBName
在第一步中指定的a不可用时调用一次。您可以在onCreate
方法上添加创建表查询- 每当您想添加新表时,只需更改
DBversion
并在onUpgrade
表中执行查询或简单地卸载然后安装该应用程序。
回答by Faxriddin Abdullayev
onCreateis called for the first time when creation of tables are needed. We need to override this method where we write the script for table creation which is executed by SQLiteDatabase. execSQL method. After executing in first time deployment, this method will not be called onwards.
当需要创建表时第一次调用onCreate。我们需要重写这个方法,在那里我们编写由 SQLiteDatabase 执行的表创建脚本。execSQL 方法。在第一次部署时执行后,此方法将不会被调用。
onUpgradeThis method is called when database version is upgraded. Suppose for the first time deployment , database version was 1 and in second deployment there was change in database structure like adding extra column in table. Suppose database version is 2 now.
onUpgrade数据库版本升级时调用此方法。假设第一次部署,数据库版本为 1,在第二次部署中,数据库结构发生了变化,比如在表中添加了额外的列。假设现在数据库版本是 2。
回答by sushant suryawanshi
Sqlite database override two methods
Sqlite 数据库重写两种方法
1) onCreate(): This method invoked only once when the application is start at first time . So it called only once
1) onCreate():该方法仅在应用程序第一次启动时调用一次。所以它只调用了一次
2)onUpgrade() This method called when we change the database version,then this methods gets invoked.It is used for the alter the table structure like adding new column after creating DB Schema
2)onUpgrade() 当我们改变数据库版本时调用这个方法,然后这个方法被调用。它用于改变表结构,如创建DB Schema后添加新列
回答by Enamul Haque
You can create database & table like
您可以创建数据库和表
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);
}
}
Note : if you want create another table or add columns or no such table, just increment the VERSION
注意:如果你想创建另一个表或添加列或没有这样的表,只需增加 VERSION
回答by phreakhead
If you forget to provide a "name" string as the second argument to the constructor, it creates an "in-memory" database which gets erased when you close the app.
如果您忘记提供“名称”字符串作为构造函数的第二个参数,它会创建一个“内存中”数据库,当您关闭应用程序时该数据库将被删除。
回答by Bharat Lalwani
no such table found is mainly when you have not opened the SQLiteOpenHelper
class with getwritabledata()
and before this you also have to call make constructor with databasename & version.
And OnUpgrade
is called whenever there is upgrade value in version number given in SQLiteOpenHelper
class.
找不到这样的表主要是当您没有打开SQLiteOpenHelper
类时getwritabledata()
,在此之前您还必须使用数据库名称和版本调用 make 构造函数。并且OnUpgrade
在SQLiteOpenHelper
类中给出的版本号中有升级值时调用。
Below is the code snippet (No such column found may be because of spell in column name):
下面是代码片段(没有找到这样的列可能是因为列名中的拼写):
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);
}
}