Android SQLiteOpenHelper onCreate()/onUpgrade()何时运行?

Android SQLiteOpenHelper onCreate()/onUpgrade()何时运行?,android,sqlite,android-sqlite,sqlexception,sqliteopenhelper,Android,Sqlite,Android Sqlite,Sqlexception,Sqliteopenhelper,我已经在我的SQLiteOpenHelperonCreate()中创建了我的表,但是收到了 SQLiteException: no such table 或 错误。为什么? 注意: (这是每周数十个类似问题的合并摘要。尝试在此处提供“规范”的社区wiki问题/答案,以便所有这些问题都可以指向一个好的参考。) 当数据库实际打开时调用回调,例如通过调用。创建数据库辅助对象本身时,不会打开数据库 SQLiteOpenHelper对数据库文件进行版本设置。版本号是传递给的int参数。在数据库文件中,版

我已经在我的
SQLiteOpenHelper
onCreate()
中创建了我的表,但是收到了

SQLiteException: no such table

错误。为什么?

注意:

(这是每周数十个类似问题的合并摘要。尝试在此处提供“规范”的社区wiki问题/答案,以便所有这些问题都可以指向一个好的参考。)

当数据库实际打开时调用回调,例如通过调用。创建数据库辅助对象本身时,不会打开数据库

SQLiteOpenHelper
对数据库文件进行版本设置。版本号是传递给的
int
参数。在数据库文件中,版本号存储在中

onCreate()
仅在数据库文件不存在且刚刚创建时运行。如果
onCreate()
成功返回(不引发异常),则假定使用请求的版本号创建数据库。作为暗示,您不应该自己在
onCreate()
中捕获
SQLException
s

只有当数据库文件存在,但存储的版本号低于构造函数中请求的版本号时,才会调用
onUpgrade()
onUpgrade()
应将表架构更新为请求的版本

在代码(
onCreate()
)中更改表架构时,应确保数据库已更新。两种主要方法:

  • 删除旧的数据库文件,以便再次运行
    onCreate()
    。在开发时,您可以控制已安装的版本,并且数据丢失不是问题,因此这通常是首选。删除数据库文件的一些方法:

    • 卸载应用程序。使用应用程序管理器或从shell中卸载.package.name

    • 清除应用程序数据。使用应用程序管理器

  • 增加数据库版本,以便调用
    onUpgrade()
    。由于需要更多的代码,这稍微复杂一些

    • 对于不存在数据丢失问题的开发时架构升级,您可以在中使用
      execSQL(“如果存在,请删除表”)
      in删除现有表,然后调用
      onCreate()
      重新创建数据库

    • 对于已发布的版本,您应该在
      onUpgrade()
      中实现数据迁移,这样您的用户就不会丢失数据


  • 根据Jaskey的要求,在此处进一步添加缺失点

    数据库版本存储在
    SQLite
    数据库文件中。

    catch是构造函数

    SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
    
    因此,当使用
    名称调用数据库帮助器构造函数时(第二个参数),平台将检查数据库是否存在,如果数据库存在,它将从数据库文件头获取版本信息并触发正确的回调

    正如前面的回答中已经解释的,如果名称为的数据库不存在,它将触发
    onCreate

    下面的解释用一个例子解释了
    onUpgrade
    案例

    比如说,您的第一个应用程序版本有
    DatabaseHelper
    (扩展
    SQLiteOpenHelper
    ),构造函数传递的版本为
    1
    ,然后您提供了一个升级的应用程序,新的源代码传递的版本为
    2
    ,然后,当构建
    DatabaseHelper
    时,平台会自动触发
    onUpgrade
    ,方法是看到文件已经存在,但版本低于您传递的当前版本

    现在假设您计划提供第三个版本的应用程序,db版本为
    3
    (只有在修改数据库模式时,db版本才会增加)。在这种增量升级中,您必须以增量方式从每个版本编写升级逻辑,以获得更好的可维护代码

    下面的伪代码示例:

    @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);
      }
    }
    
    注意在案例
    1
    2
    中缺少的
    break
    语句。这就是我所说的增量升级

    假设旧版本为
    2
    ,新版本为
    4
    ,则逻辑将数据库从
    2
    升级到
    3
    ,然后升级到
    4

    如果旧版本是
    3
    ,而新版本是
    4
    ,它将只运行
    3
    4

    onCreate()

  • 当我们第一次创建数据库时(即数据库不存在)
    onCreate()
    使用传入的版本创建数据库
    SQLiteOpenHelper(上下文上下文、字符串名称、SQLiteDatabase.CursorFactory、int版本)

  • onCreate()
    方法是创建您定义的表并执行您编写的任何其他代码。但是,仅当应用程序的数据目录(
    /data/data/your.apps.classpath/databases
    )中缺少SQLite文件时,才会调用此方法

  • 如果已更改代码并在模拟器中重新启动,则不会调用此方法。如果要运行
    onCreate()
    ,则需要使用adb删除SQLite数据库文件

  • onUpgrade()

  • SQLiteOpenHelper
    应该调用超级构造函数
  • 只有当版本整数大于应用程序中运行的当前版本时,才会调用
    onUpgrade()
    方法
  • 如果希望调用
    onUpgrade()
    方法,则需要在代码中增加版本号

  • 从仿真器或设备卸载应用程序。再次运行应用程序。(当数据库已经存在时,不会执行OnCreate())

    在扩展
    SQLiteOpenHelper

  • 
    
    @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);
      }
    }
    
    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    
    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);
      }
    }
    
    <item>
        INSERT INTO table_name(id, name) VALUES(1, \"some_value\")
    </item>