2013-11-25 2 views
6

Я следил за информацией, которую я нашел на веб-сайте, о прикреплении базы данных sqlite с целью копирования таблицы из одного sqlite db в другой, но я не могу заставить ее работать. Я пытаюсь прикрепить базу данных с этим кодом: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

(удалено ......) –

+0

Одиночных кавычек вокруг 'tempDb' (в инструкции' ATTACH') не должно быть. Одиночные кавычки в SQLite предназначены в первую очередь для разграничения строковых литералов. Заявление должно принимать форму 'ATTACH 'drive/path/database_name' AS database_alias; ' – PositiveLogic

+0

Каково значение' DB_PATH'? –

ответ

5

@Phil. Да, я получил его но я действительно не помню, какова реальная проблема, руды, поэтому я просто напишу упрощенную последовательность шагов, которые я нашел в своем коде относительно копирования из 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); 

Конечно, есть OnCreate методы отсутствуют для обоих SQLiteOpenHandler-х, но это до приложения, что делается там.

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

2

Я выясняю, 2 способа прикрепить базу данных.

  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() вызываются вместе во время транзакции. enter image description here

+0

Это не работает, потому что вызов «getReadableDatabase()» автоматически вызывает «onUpgrade()». Итак, как выполнить команду attach перед вызовом onUpgrade()? –

+0

hmmm ... Я думаю, что sqlite не хочет, чтобы вы подключались до onUpgrade() ... –

+0

Я выясняю способ подключения до onUpgrade(), см. Обновленный ответ ~ –

Смежные вопросы