2013-11-21 52 views
3

我正在创建一个数据库,引用另一个数据库中的键的过程。从本质上讲,我有一个数据导入,我想保持与将会更改的数据分开,但如果可能,我想通过FOREIGN KEY引用其他密钥。据我所知,我需要首先附加数据库才能实现这一点。这里是德相关的代码至今:Android与SQLiteOpenHelper ATTACH sqlite数据库

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

回答

4

我想出了一种方法来使它工作,我并不特别自豪,但它做到了。如果您在连接数据库时无法进行事务处理,请先结束事务。

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

您是否能够与附加的数据库进行交互?我也是这样做的,但是当我引用附加的数据库时,我得到一个*没有这样的表*错误(例如:'SELECT * FROM names.mytable'。 – Phil

+0

我最终拒绝了这个,转而采用完全不同的方式但是,我回到它,我会让你知道,如果它的工作... – PearsonArtPhoto

+0

这是行不通的。我在onUpgrade()上使用此代码,我得到这个错误“如果我不使用“db.setTransactionSuccessful()”,“db.endTransaction()”,“db.beginTransaction()”,那么出现这个错误“无法在数据库中附加数据库”交易“ –

0

我有同样的问题时,我想连接数据库,同时更新数据库,我所做的只是改变一个静态全局变量时的onUpdate()被调用,右后this.getReadableDatabase()或this.getWritableDatabase ()(实际上是调用onCreate/onUpdate方法的函数)我检查全局变量的值并运行包含attach函数的整个代码。这样你就不用在onCreate()或onUpgrade()方法中附加内容,而是在执行它们之后。

我不确定这种方法在指定的情况下是否可用,但我只是想我会提及如果别人碰到这个问题,我会如何解决它。

+0

我在onUpgrade()方法中有同样的问题,我尝试了很多解决方案但没有成功。请详细说明。 –