java Sqlite 数据库 onUpgrade() 不会被调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10664935/
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
Sqlite database onUpgrade() does not get called
提问by rawcoder064
I am working on an android application where i used existing sqlite database in the asset folder. So i actually copy the database from that folder. User can also save their own data(mark any content as favorite).
我正在开发一个 android 应用程序,我在资产文件夹中使用了现有的 sqlite 数据库。所以我实际上是从那个文件夹复制数据库。用户还可以保存自己的数据(将任何内容标记为收藏)。
I uploaded a version in the market. Now i want to add some new data in the database and uploaded a new version. If user update the app from the market i want to keep the user data(from previous version) and add the new data as well. I have done some google and found that on upgrade method should do the trick. But I am changing the DATABASE_VERSION from code but the on upgrade method does not get call. I am wondering i have missed something. Here is my code:
我在市场上上传了一个版本。现在我想在数据库中添加一些新数据并上传一个新版本。如果用户从市场更新应用程序,我想保留用户数据(来自以前的版本)并添加新数据。我已经做了一些谷歌,发现升级方法应该可以解决问题。但是我正在从代码中更改 DATABASE_VERSION 但升级方法没有得到调用。我想知道我错过了什么。这是我的代码:
public class DataBaseHelper extends SQLiteOpenHelper {
private static String DB_PATH = "/data/data/riskycoder.login/databases/";
public static String DB_NAME = "datenbank_EN.sqlite";
private SQLiteDatabase myDataBase;
private final Context myContext;
private static final int DATABASE_VERSION = 1;
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
this.myContext = context;
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
} else {
this.getWritableDatabase();
try {
this.close();
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
}
if (checkDB != null)
checkDB.close();
return checkDB != null ? true : false;
}
private void copyDataBase() throws IOException {
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[2048];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
//myDataBase.setVersion(DATABASE_VERSION);
}
public void openDataBase() throws SQLException {
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE);
Log.d("Test", "Database version: " +myDataBase.getVersion());
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d("Test", "in onUpgrade. Old is: " + oldVersion + " New is: " + newVersion);
}
}
}
回答by Alex Lockwood
onUpgrade()
is only called if a change in the database version number is detected. Increment the database version as follows:
onUpgrade()
仅在检测到数据库版本号发生变化时才调用。增加数据库版本如下:
private static final int DATABASE_VERSION = 2;
回答by Avishek
Change your onUpgrade to the following
将您的 onUpgrade 更改为以下内容
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(newVersion > oldVersion){
myContext.deleteDatabase(DB_NAME);
}
}
And also change your createDataBase() like below,
并更改您的 createDataBase() 如下所示,
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
// By calling this method here onUpgrade will be called on a
// writable database, but only if the version number has been increased
this.getWritableDatabase();
}
dbExist = checkDataBase();
if(!dbExist){
//By calling this method an empty database will be created into the default system path
//of the application so we will be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
At the end increase your database version and run it again. onUpgrade
doesn't get called till you call getReadableDatabase()
or similar functions.
最后增加您的数据库版本并再次运行它。onUpgrade
在您调用getReadableDatabase()
或类似函数之前不会被调用。
Hope this helps
希望这可以帮助
回答by Yaqub Ahmad
Try this (increase the DATABASE_VERSION) & the onUpdate() will be called:
试试这个(增加 DATABASE_VERSION)& onUpdate() 将被调用:
private static final int DATABASE_VERSION = 2;
回答by Barak
Assuming you did change the DATABASE_VERSION, you still have to put code in the onUpgrade to make it happen. It's not magical, you have to tell it what to do.
假设您确实更改了 DATABASE_VERSION,您仍然需要将代码放入 onUpgrade 以使其发生。这并不神奇,你必须告诉它该做什么。
In your case you need to:
在您的情况下,您需要:
1) copy the old database (give it a new name)
2) copy in your new database
3) read the data from the old database
4) copy any differences into the new database
5) delete the old database
1)复制旧数据库(给它一个新名称)
2)复制到你的新数据库中
3)从旧数据库中读取数据
4)将任何差异复制到新数据库中
5)删除旧数据库
EDIT
编辑
Assuming you ship the DB in the assets folder you would copy it for use like so:
假设您将数据库发送到资产文件夹中,您将复制它以供使用,如下所示:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// First copy old db
InputStream bakInput = getActivity().getAssets().open(dbname);
String bakFileName = getActivity().getAssets() + "YourDB.old";
OutputStream bakOutput = new FileOutputStream(bakFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = bakInput.read(buffer)) > 0) {
bakOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
// delete the old db
File delDB = new File(getActivity().getAssets() + "YourDB");
boolean deleted = file.delete();
// Copy in the new db
InputStream myInput = getActivity().getAssets().open("YourDB");
String outFileName = MAIN_DB_PATH + dbname;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
// add code here to get changes user has made to db and move them to updated db
// delete the old db copy
File delDB = new File(getActivity().getAssets() + "YourDB.old");
boolean deleted = file.delete();
}