我跟踪了我在网上发现的一些关于附加sqlite数据库的信息,目的是将一个表从一个sqlite数据库复制到另一个sqlite数据库,但我似乎无法让它工作。我尝试使用以下代码附加数据库:
DB_PATH = context.getDatabasePath("WineDB.sqlite").toString();
SQLiteDatabase backupDatabase = backupDBHandler.getWritableDatabase();
backupDatabase.execSQL("ATTACH '" + DB_PATH + "' AS 'tempDb'");
到目前为止,它运行没有错误。 然后我尝试通过从tempDb中复制它来在备份数据库中创建一个新表:
sqlDB.execSQL("CREATE TABLE my_Producent AS SELECT * FROM tempDb.my_Producent");
它崩溃并出现错误“没有这样的表”tempDb.my_Producent“但我确信该表存在于数据库”WineDB.sqlite“。我在onCreate方法中创建它,在将数据库附加到backupDatabase之前调用该方法
感谢您的帮助 干杯 user2302510
答案 0 :(得分:6)
@Phil。是的,我有它的工作。但是我真的不记得真正的问题了,所以我只会编写一个简化的步骤,我在代码中找到了关于从 firstDB 复制到 secondDB 。我在 firstDB 的SQLiteOpenHelper
中执行以下操作。
public class firstDBHandler extends SQLiteOpenHelper {
SQLiteDatabase firstDB;
//FIRST_DB_NAME is something like 'xxx1.sqlite'
private static String FIRST_DB_PATH = context.getDatabasePath(FIRST_DB_NAME).toString();
public void copyFromFirstToSecond(String secondDBName, int secondDBVersion) {
//use the same context as for the firstDBHandler
secondDBHandler = new SecondDBHandler(myContext, secondDBName, secondDBVersion);
//here you create the secondDB if it does not exist yet
try {
secondDBHandler.createDataBase();
} catch (IOException e) {
e.printStackTrace();
}
SQLiteDatabase secondDB = secondDBHandler.getWritableDatabase();
//note there are single quotation marks around FIRST_DB_PATH but none around tempDb
secondDB.execSQL("ATTACH DATABASE '" + FIRST_DB_PATH + "' AS tempDb");
//here you start to copy the tables from firstDB first by checking if the table exists in secondDB (secondDB is now the 'main' one, tempDB is the attached firstDB
secondDB.execSQL("DROP TABLE IF EXISTS main." + SECOND_DB_TABLE_NAME);
//here you create a table as a copy of
secondDB.execSQL("CREATE TABLE main." + SECOND_DB_TABLE_NAME + " AS SELECT * FROM tempDb." + FIRST_DB_TABLE_NAME);
//you can run the last two lines of code as many times as you need to copy all of the tables
//after you have copied all of them, you need to detach the tempDB
secondDB.execSQL("DETACH tempDb");
}
}
public class SecondDBHandler extends SQLiteOpenHelper {
//SECOND_DB_NAME is something like 'xxx2.sqlite'
private static String SECOND_DB_PATH = context.getDatabasePath(SECOND_DB_NAME).toString();
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
// do nothing - database already exist
} else {
//This calls onCreate method of this SecondDBHandler, where you
//create tables that you need initially (but not those which you
//intent to copy from firstDB)
this.getReadableDatabase();
this.close();
}
}
public boolean checkDataBase() {
File file = new File(SECOND_DB_PATH);
return file.exists();
}
}
然后你打电话:
FirstDBHandler firstDBHandler = new FirstDBHandler(getBaseContext(), FIRST_DB_NAME, FIRST_DB_VERSION);
firstDBHandler.getReadableDatabase();
firstDBHandler.copyFromFirstToSecond(SECOND_DB_NAME, SECOND_DB_VERSION);
当然,SQLiteOpenHandler
都缺少onCreate方法,但这取决于应用程序在那里完成的工作。
希望答案中没有错误。我自己没有测试过,只是从我更复杂的代码中提取了一个简化版本。如果有一些赞成,我会将其标记为答案。
答案 1 :(得分:2)
我找到了两种附加数据库的方法。
请勿在{{1}}和onCreate
中“附加数据库”。由于“无法在事务中附加数据库”,它将失败。
但是,您可以在初始化数据库时附加数据库,然后调用onUpgrade
以确保将创建和升级数据库。
然后你可以运行attach命令。
getReadableDatabase()
但如果你想在onUpgrade()之前做依恋,请尝试以下方式:
onCreate()中的endTransaction,然后执行attach,然后是beginTransaction
sqLiteHelper = new SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION); // new SQLiteOpenHelper
SQLiteDatabase db = sqLiteHelper.getReadableDatabase(); // make sure the database will be created
db.execSQL("ATTACH DATABASE '/databases/xx.db' AS xx;"); // do attach database
<强>原因:强>
阅读SQLiteOpenHelper.java的功能,我发现在事务期间一起调用onCreate()和onUpgrade()。