在Android中使用SQLiteOpenHelper附加sqlite数据库

3

我正在创建一个引用另一个数据库键的数据库。基本上,我有一个数据导入,我想将其与会改变的数据分开,但如果可能的话,我想通过FOREIGN KEY引用其他键。据我所知,我需要先附加数据库才能实现这一点。以下是到目前为止相关的代码:

public class LogDatabaseHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "log.db";
    private static final int DATABASE_VERSION = 1;
    private String namesDb;

    public LogDatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        namesDb=getNamesDbPath();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("ATTACH DATABASE ? AS names",new String[]{namesDb});
        StringBuilder query=new StringBuilder();
        query.append("CREATE TABLE log (");
    }
}

然而,这似乎不起作用,因为我得到了以下错误:
11-21 17:35:58.176: E/SQLiteLog(9984): (1) statement aborts at 5: [ATTACH DATABASE ? AS names] cannot ATTACH database within transaction
11-21 17:35:58.176: D/AndroidRuntime(9984): Shutting down VM
11-21 17:35:58.176: W/dalvikvm(9984): threadid=1: thread exiting with uncaught exception (group=0x41a21700)
11-21 17:35:58.191: E/AndroidRuntime(9984): FATAL EXCEPTION: main
11-21 17:35:58.191: E/AndroidRuntime(9984): android.database.sqlite.SQLiteException: cannot ATTACH database within transaction (code 1)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:734)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1603)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at com.kd7uiy.hamfinder.LogDatabaseHelper.onCreate(LogDatabaseHelper.java:27)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
11-21 17:35:58.191: E/AndroidRuntime(9984):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)

我该怎样使这个工作起来?

1
你可能需要跳过 SQLiteOpenHelper 或者对其进行分叉。在后一种情况下,你可以移除包装 onCreate() 的标准事务(自己处理它),或者给自己一个机会在任何事务边界之外运行 ATTACH - CommonsWare
2个回答

3

我找到了一种让它工作的方法,虽然不是特别自豪,但是它能够完成任务。如果在附加数据库时不能进行事务处理,则先结束此事务。

db.setTransactionSuccessful();
db.endTransaction();
db.execSQL("ATTACH DATABASE ? AS names",new String[]{namesDb});
db.beginTransaction();

你能够与附加的数据库进行交互吗?我也在做这个,但是当我引用附加的数据库时,会出现“没有这样的表”错误(例如:SELECT * FROM names.mytable)。 - Phil
我最终选择了一种完全不同的管理方式,因此拒绝了这种方法。不过,我会回来尝试它,如果有效的话,我会告诉你... - PearsonArtPhoto
它没有运作。我在“onUpgrade()”上使用了这个代码,但是我收到了这个错误:“无法执行此操作,因为没有当前事务”。如果我不使用“db.setTransactionSuccessful()”,“db.endTransaction()”,“db.beginTransaction()”,那么就会出现这个错误:“无法在事务中附加数据库”。 - Ashish Tiwari
这个解决方案不起作用,还会让人感到困惑。你应该取消它作为被接受的答案。 - Nimrod Dayan

0

当我想在更新数据库时附加数据库时,我遇到了同样的问题。我所做的就是在onUpdate()被调用时更改一个静态全局变量,并在执行this.getReadableDatabase()或this.getWritableDatabase()(实际上是调用onCreate/onUpdate方法的函数)后检查全局变量的值并运行包含附加函数的整个代码。这样,您不会在onCreate()或onUpgrade()方法内部执行附加操作,而是在执行它们之后立即执行。

我不确定这种方法是否适用于问题中指定的情况,但我只是想提一下我如何解决这个问题,以防其他人也遇到了这个问题。


我在onUpgrade()方法中遇到了同样的问题,我尝试了很多解决方案但都没有成功。请详细说明一下。 - Ashish Tiwari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接