【问题标题】:Delete entire database onUpgrade in Android?在Android中删除整个数据库onUpgrade?
【发布时间】:2014-09-01 19:03:41
【问题描述】:

如果 onUpgrade 被调用,我会尝试完全删除数据库。根据这个 SO 问题:How to delete SQLite database from Android programmatically 我可以调用context.deleteDatabase(String dbName),但我无法在 onUpgrade 方法中获取上下文。在 onUpgrade 中有一个传入的 db 对象,我看到您可以使用 db.deleteDatabase() 方法,但它需要一个文件。我没有 db 文件。有什么办法可以做db.deleteSelf 或类似的事情吗?我知道我可以只删除表等而不是完全删除数据库,但我的数据库结构已经完全改变,我宁愿只调用deleteDb();,然后再次调用onCreate(db);

【问题讨论】:

    标签: android database sqlite android-sqlite


    【解决方案1】:

    如果 onUpgrade 被调用,我会尝试完全删除数据库。

    请记住,清除所有用户数据可能会使用户非常暴躁,就像“Play 商店的一星评级”级别的暴躁一样。

    另外,你想要的东西是相当冒险的。您可能会搞砸架构版本元数据。即使假设您尝试做的事情通常是明智的,我建议您只需在SQLiteDatabase 上调用execSQL() 来为您创建的每个表执行DROP TABLE 语句(加上DROP INDEX 等) .

    我只能调用 context.deleteDatabase(String dbName),但我无法在 onUpgrade 方法中获取上下文

    您的SQLiteOpenHelper 子类在其构造函数中传递了Context。虽然这不是通过 getter 方法公开的,但您可以将 Context 自己保存在数据成员中。

    我知道我可以只删除表等而不是完全删除数据库,但是我的数据库结构已经完全改变,我宁愿只调用 deleteDb();然后 onCreate(db);再次。

    除了调用onCreate() 不会创建您的数据库。您将删除数据库。所以,除非你自己创建一个空的数据库文件,否则onCreate() 会崩溃。 onCreate() 在创建数据库的事件中被调用;它不是“为我创建一个数据库”。

    此外,如果此应用仍在开发中,请在再次运行之前卸载该应用,这将清除数据库(假设它存储在典型位置)。

    【讨论】:

    • 那么如果我在 onUpgrade 中删除一个表然后调用 onCreate(db);它不应该崩溃,因为它仍然有一个有效的数据库?
    • onUpgrade 在活动事务中被调用;此时您无法删除该文件。 (当最后处理的文件关闭时,文件实际上会被删除,这将在onCreate 调用之后。)
    • @EGHDK:是的,删除数据库的内容(例如,DROP TABLE)并链接到onCreate() 是安全的。只需注意拿着火炬和干草叉在您所在位置行进的用户。
    • 知道了。感谢您的提醒。用户实际上无权使用数据库做任何事情。我只是使用数据库通过应用程序发送数据。
    【解决方案2】:

    当您不关心旧数据时,您实际上并不需要旧数据库来创建新数据库。 只需给新数据库一个不同的名称,它就会正常创建。 您可以随时删除旧的数据库文件(即,在开始主要活动时,当您有 Context 时),并且不需要关心这是在您访问新数据库之前还是之后发生的。

    【讨论】:

      【解决方案3】:

      所以我猜你的 Database-Class 扩展了 SQLiteOpenHelper 并且通过这个类型 SQLiteOpenHelper(context:Context,name:String,factory:CursorFactory,version:int) 的默认构造函数是必需的。这基本上意味着您需要在创建实例时将 Context 传递给您的 Database-Class。这是您将上下文引用保存到局部变量的选项:

      public class DatabaseHelper extends SQLiteOpenHelper {
      
          private Context mCtx;
      
          public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
              super(context, name, factory, version);
              this.mCtx = context;
          }
      
          @Override
          public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i2) {
              mCtx.deleteDatabase("DB_NAME")
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-21
        • 1970-01-01
        • 1970-01-01
        • 2015-03-08
        相关资源
        最近更新 更多