Sqlite – прикрепить базу данных

Я следил за некоторой информацией, которую я нашел в Интернете, о том, чтобы привязать базу данных sqlite для копирования таблицы из одного sqlite db в другой, но я не могу заставить ее работать. Я пытаюсь прикрепить базу данных с помощью этого кода:

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.

Спасибо за любую помощь Cheers user2302510

@Фил. Да, у меня это работает. Однако я не помню, какова была настоящая проблема, поэтому я просто напишу упрощенную последовательность шагов, которые я нашел в своем коде относительно копирования из firstDB в secondDB . Я выполняю следующие операции в SQLiteOpenHelper для firstDB .

 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 отсутствуют методы SQLiteOpenHandler , но это зависит от того, что там сделано.

Надеюсь, ответ не содержит ошибок. Я сам его не тестировал, просто извлек упрощенную версию из моего более сложного кода. Если у него есть несколько upvotes, я буду отмечать это как ответ.

Я нахожу два способа подключения базы данных.

  1. НЕ «прикрепляйте базу данных» в onCreate и onUpgrade . Он не удастся из-за «Не удается привязать базу данных в транзакции». Но вы можете прикрепить базу данных при инициализации базы данных, а затем вызвать getReadableDatabase() чтобы убедиться, что база данных будет создана и обновлена. Затем вы можете запустить команду attach.

     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 
  2. Но если вы хотите подключиться до onUpgrade () , попробуйте следующим образом:

EndTransaction в onCreate (), затем присоединяйте, затем beginTransaction

  public void onCreate(SQLiteDatabase db) { this.createTables(db); // do the normal onCreate() stuff db.setTransactionSuccessful(); db.endTransaction(); // end transaction, so that you can do attach db.execSQL("ATTACH DATABASE '/databases/xx.db' AS xx;"); // do attach database db.execSQL("DETACH DATABASE xx;"); // detach database db.beginTransaction(); // begin transation again } 

Причина:

Прочитайте функцию SQLiteOpenHelper.java, я узнаю, что onCreate () и onUpgrade () вызываются вместе во время транзакции. Введите описание изображения здесь