SQLiteOpenHelper在更改数据库版本时不会更新数据库

时间:2017-10-19 21:42:49

标签: android sql database sqlite sqliteopenhelper

我有关于SQLiteOpenHelper的问题。 我创建了一个单例来访问数据库。在构造函数中,我使用DATABASE_VERSION调用super方法(SQLiteOpenHelper),所以如果我增加DATABASE_VERSION,应该调用onUpgrade吗? 但是从未调用onUpgrade。 是否有其他属性可以更改以升级数据库或其他什么?

谢谢!

代码示例:

/home/myusername/nltk_data/corpora/stopwords

//主要活动代码部分:

private static final int DATABASE_VERSION = 101;
private static final String DATABASE_NAME = "dbName.db";

private static final String SQL_CREATE_TESTDB_TABLE = "CREATE TABLE TESTTABLE (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)";
private static final String SQL_DELETE_TESTDB_TABLE = "DROP TABLE IF EXISTS TESTTABLE";    


//Singleton
private static TestDatabase testDatabase = null;

public static TestDatabase getTestDatabase(Context context){
    if(testDatabase == null){
        testDatabase = new TestDatabase(context);
    }
    return testDatabase;
}

//Constructor
private TestDatabase(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);

    this.getWritableDatabase(); //DB should upgrade?
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL(SQL_DELETE_TESTDB_TABLE);
    this.onCreate(db);
}

@Override
public void onCreate(SQLiteDatabase db) {
    //create table
    db.execSQL(SQL_CREATE_TESTDB_TABLE);
}

3 个答案:

答案 0 :(得分:1)

在TestDatabase类(扩展SQLiteOpenHelper的类)上,需要覆盖onUpgrade方法。我相信你已经有了onCreate方法。样本将是,

 def listsave():
 list1 = []
 x = None
  while True:
  x = input('Enter integer (q to quit):')
    if x != 'q':
     list1.append(int(x))
else:
    return sum(list1)/len(list1)

答案 1 :(得分:0)

数据库名称常量通常不包含' .db'扩展,但如果这导致您的错误,我会感到惊讶。

getWriteableDatabase()调用应足以触发onCreate()或onUpgrade(),但是编译器可能会对其进行优化,因为它的结果未被使用?

我会尽快测试这两个选项并使用结果进行编辑。

编辑:当我测试时,这些都没有引起问题,你确定在某处调用了getTestDatabase吗?如果没有,那么实际上并没有创建实例,这可以解释为什么代码没有运行。

答案 2 :(得分:0)

根据我的评论。我确定我遇到了同样的问题,但我在this.getWriteableDatabase();添加了一个断点并进行了调试。然后我尝试在

处进入代码(提出警告并仍然Sources for Android API 26 Platform not found
public SQLiteDatabase getWritableDatabase() {
    throw new RuntimeException("Stub!");
}

但此后一直有效。因此,我建议尝试做同样的事情(也许尝试清理和重建)。

我的代码(下面)是发布的代码的副本,除了我编写表创建代码并添加了一些日志记录。日志记录的结​​果非常符合: -

10-20 21:12:48.879 24448-24448/? D/TESTDB: getTestDatabase invoked
10-20 21:12:48.879 24448-24448/? D/TESTDB: Calling Constructor from singleton
10-20 21:12:48.879 24448-24448/? D/TESTDB: Constructor Invoked
10-20 21:18:30.177 29719-29719/? D/TESTDB: getTestDatabase invoked
10-20 21:18:30.177 29719-29719/? D/TESTDB: Calling Constructor from singleton
10-20 21:18:30.177 29719-29719/? D/TESTDB: Constructor Invoked
10-20 21:18:44.181 29792-29792/? D/TESTDB: getTestDatabase invoked
10-20 21:18:44.181 29792-29792/? D/TESTDB: Calling Constructor from singleton
10-20 21:18:44.181 29792-29792/? D/TESTDB: Constructor Invoked

从这里注意相同的代码开始工作并调用onCreate ????

10-20 21:21:29.644 31659-31659/? D/TESTDB: getTestDatabase invoked
10-20 21:21:29.644 31659-31659/? D/TESTDB: Calling Constructor from singleton
10-20 21:21:29.644 31659-31659/? D/TESTDB: Constructor Invoked
10-20 21:21:29.666 31659-31659/? D/TESTDB: Oncreate Invoked
10-20 21:25:38.967 1069-1069/? D/TESTDB: getTestDatabase invoked
10-20 21:25:38.967 1069-1069/? D/TESTDB: Calling Constructor from singleton
10-20 21:25:38.967 1069-1069/? D/TESTDB: Constructor Invoked
10-20 21:26:06.221 1069-1069/? D/TESTDB: Oncreate Invoked
10-20 21:28:38.297 3941-3941/? D/TESTDB: getTestDatabase invoked
10-20 21:28:38.297 3941-3941/? D/TESTDB: Calling Constructor from singleton
10-20 21:28:38.297 3941-3941/? D/TESTDB: Constructor Invoked
10-20 21:28:44.602 4040-4040/? D/TESTDB: getTestDatabase invoked
10-20 21:28:44.602 4040-4040/? D/TESTDB: Calling Constructor from singleton
10-20 21:28:44.602 4040-4040/? D/TESTDB: Constructor Invoked
10-20 21:34:39.608 9786-9786/? D/TESTDB: getTestDatabase invoked
10-20 21:34:39.608 9786-9786/? D/TESTDB: Calling Constructor from singleton
10-20 21:34:39.608 9786-9786/? D/TESTDB: Constructor Invoked
10-20 21:36:48.139 10495-10495/? D/TESTDB: getTestDatabase invoked
10-20 21:36:48.139 10495-10495/? D/TESTDB: Calling Constructor from singleton
10-20 21:36:48.139 10495-10495/? D/TESTDB: Constructor Invoked
10-20 21:36:48.188 10495-10495/? D/TESTDB: Oncreate Invoked

请注意!我没有为上面的一些运行删除数据库(我最后一次运行)。

在onUpgrade上将版本更改为102,名为

10-20 21:41:49.007 15098-15098/? D/TESTDB: getTestDatabase invoked
10-20 21:41:49.007 15098-15098/? D/TESTDB: Calling Constructor from singleton
10-20 21:41:49.007 15098-15098/? D/TESTDB: Constructor Invoked
10-20 21:41:49.011 15098-15098/? D/TESTDB: onUpgrade invoked

我使用的代码(请原谅肆无忌惮的剽窃 :)),现在版本为102(最初使用101): -

public class TestDatabase extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 102;
    private static final String DATABASE_NAME = "dbName.db";

    //Singleton
    private static TestDatabase testDatabase = null;

    public static TestDatabase getTestDatabase(Context context) {
        Log.d("TESTDB","getTestDatabase invoked");
        if (testDatabase == null) {
            Log.d("TESTDB", "Calling Constructor from singleton");
            testDatabase = new TestDatabase(context);
        }
        return testDatabase;
    }

    private TestDatabase(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        Log.d("TESTDB","Constructor Invoked");
        this.getWritableDatabase();
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.d("TESTDB","Oncreate Invoked");
        String tblcrt = "CREATE TABLE IF NOT EXISTS testtable (" +
                "_id INTEGER PRIMARY KEY," +
                "COL1 TEXT" +
                ")";
        db.execSQL(tblcrt);

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        Log.d("TESTDB","onUpgrade invoked");
    }
}

以及: -

......
TestDatabase testdb;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setViewIDs();
    setDBViewerButton(mButton1); // setup Button 1 for DBViewer

    testdb = TestDatabase.getTestDatabase(this);
    .....
}