将数据从一个数据库表复制到另一个数据库表。

时间:2014-06-04 06:00:38

标签: android sqlite

我的项目中有两个数据库,一个附带.apk,另一个基于用户交互。现在,在第一次运行时,我想将一些数据从已发送的数据库复制到内部数据库。我有以下代码片段:

if(personalities !=null && personalities.moveToFirst()){
                        dbHelper.open();
                        do{
                            String name = personalities.getString(personalities.getColumnIndexOrThrow("Name")); 
                            String displayBirthday = personalities.getString(personalities.getColumnIndexOrThrow("DOB")); 
                            String imagePath = personalities.getString(personalities.getColumnIndexOrThrow("imageUri")); 
                            //      System.out.println("Ext Db Name: "+B+" DOB: "+C+" and imageUri: "+D); 



                            insertAdhocCase(name,displayBirthday,imagePath, "Person", "0", FRIEND_NAME);


                            insertInDb(name,displayBirthday,imagePath, "Person","0", FRIEND_NAME );




                        }while(personalities.moveToNext());

                    } 

但是我收到以下错误:(即使在打开与db的连接后 - dbHelper.open();)

06-04 11:27:04.897: E/AndroidRuntime(7094): FATAL EXCEPTION: AsyncTask #1
06-04 11:27:04.897: E/AndroidRuntime(7094): java.lang.RuntimeException: An error occured while executing doInBackground()
06-04 11:27:04.897: E/AndroidRuntime(7094):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at java.lang.Thread.run(Thread.java:838)
06-04 11:27:04.897: E/AndroidRuntime(7094): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.exa.digitalanniversaries/databases/Bdr
06-04 11:27:04.897: E/AndroidRuntime(7094):     at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1437)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at com.exa.digitalanniversaries.DBAdapter.insertAdhoc(DBAdapter.java:393)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at com.exa.digitalanniversaries.TheWizardOfOz.insertAdhocCase(TheWizardOfOz.java:738)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at com.exa.digitalanniversaries.TheWizardOfOz$AsyncActivity.doInBackground(TheWizardOfOz.java:644)
06-04 11:27:04.897: E/AndroidRuntime(7094):     at com.exa.digitalanniversaries.TheWizardOfOz$AsyncActivity.doInBackground(TheWizardOfOz.java:1)

这样做的正确方法是什么?即使我在交易前打开数据库,为什么它会给我这个特定的错误?

3 个答案:

答案 0 :(得分:0)

希望你不会遗漏任何内容:

  • 创建两个不同数据库的两个不同连接。
  • 从DB1
  • 逐行选择数据
  • 逐行将数据插入DB2
  • 从DB1完成复制(关闭连接)
  • 完成对DB2的插入(关闭连接)

答案 1 :(得分:-2)

dbHelper.close()语句末尾关闭数据库(do..while),它应该可以正常工作。祝你好运!

更新: 此外,您可以在打开数据库之前使用dbHelper.isOpen()方法,以确保您不会收到错误。

答案 2 :(得分:-2)

在DBHelper类的构造函数中,检查用户数据库是否存在,如果不存在,则将内容从apk包复制到用户数据库。请在下面找到示例代码。

/**
 * Constructor
 * 
 * @param context
 *            Context to be used
 */
public DBHelper(Context context) {

    super(context, context.getFilesDir().getAbsolutePath() + "/database/"
            + DB_NAME, null, DB_VERSION);
    mContext = context;

    if (!checkDataBaseExistence())
        copyDB();

}

/*
 * (non-Javadoc)
 * 
 * @see
 * android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite
 * .SQLiteDatabase)
 */
public void onCreate(SQLiteDatabase db) {
}

private boolean checkDataBaseExistence() {

    // database to be verified
    SQLiteDatabase dbToBeVerified = null;

    try {
        // get database path
        String dbPath = mContext.getFilesDir().getAbsolutePath()
                + "/database/" + DB_NAME;

        // DB_PATH + DB_NAME;

        // try to open the database
        dbToBeVerified = SQLiteDatabase.openDatabase(dbPath, null,
                SQLiteDatabase.OPEN_READWRITE);

    } catch (SQLiteException e) {
        // do nothing since the database does not exist
    }

    // in case it exists, close it
    if (dbToBeVerified != null) {
        // close DB
        dbToBeVerified.close();

    }

    // in case there is a DB entity, the DB exists
    return dbToBeVerified != null ? true : false;
}

private void copyDB() {

    InputStream myInput = null;
    OutputStream myOutput = null;

    try {
        // Open your local db as the input stream
        myInput = mContext.getAssets().open("database/" + DB_NAME);

        // Path to the just created empty db
        File file = new File(mContext.getFilesDir().getAbsolutePath()
                + "/database");
        file.mkdirs();

        String outFileName = mContext.getFilesDir().getAbsolutePath()
                + "/database/" + DB_NAME;

        // Open the empty db as the output stream
        myOutput = new FileOutputStream(outFileName);

        // transfer bytes from the input file to the output file
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

    } catch (FileNotFoundException e) {
        // handle your exception here
    } catch (IOException e) {
        // handle your exception here
    } finally {
        try {
            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();

        } catch (Exception e) {
            // handle your exception here
        }
    }

}