2016-07-14 12 views
0

私はassets/databases/minitest.dbに格納されているsqliteデータベースを持っており、それをassetsフォルダからローカルファイルシステムにコピーして開きます。sqliteのデータベースにテーブルがありません

私はそれを開くと、テーブルが見つかりません例外が発生します。

私は確かにそれはデータベース自体に問題がないと確信しています。なぜなら、私はsqliteビューアで開くと、それはうまく見えるからです。私は約2時間この問題を訴えてきましたが、私はたくさんの似たような質問を見ましたが、解決策のどれもうまくいかないので、私は本当に何をすべきかわかりません。

コード:

mydatabase = new DataBaseHelper(c).myDataBase; 
Cursor mCursor = mydatabase.rawQuery("SELECT third FROM Trigrams WHERE first='" + first.toLowerCase() + "' AND second ='" + second.toLowerCase() + "' ORDER BY freq DESC LIMIT 0,3", null); 

コンプリートDataBaseHelper:

class DataBaseHelper extends SQLiteOpenHelper { 
    private Context mycontext; 
    private static final String DB_NAME = "minitest.db";  
    private static final String DB_PATH = "/data/data/" +  BuildConfig.APPLICATION_ID + "/databases/"; 
    private static final int DB_VERSION = 3; 
    public SQLiteDatabase myDataBase; 

    public DataBaseHelper(Context context) throws IOException { 
     super(context, DB_NAME, null, DB_VERSION); 
     this.mycontext = context; 
     boolean dbexist = checkdatabase(); 
     if (dbexist) { 
      System.out.println("Database exists"); 
      opendatabase(); 
     } else { 
      System.out.println("Database doesn't exist"); 
      createdatabase(); 
      opendatabase(); 
     } 
    } 

    public void createdatabase() throws IOException { 
     boolean dbexist = checkdatabase(); 
     if (dbexist) { 
      System.out.println(" Database exists."); 
     } else { 
      this.getReadableDatabase(); 
      try { 
       copydatabase(); 
      } catch (IOException e) { 
       throw new Error("Error copying database"); 
      } 
     } 
    } 

    private boolean checkdatabase() { 

     boolean checkdb = false; 
     try { 
      String myPath = DB_PATH + DB_NAME; 
      File dbfile = new File(myPath); 
      checkdb = dbfile.exists(); 
     } catch (SQLiteException e) { 
      System.out.println("Database doesn't exist"); 
     } 
     return checkdb; 
    } 

    private void copydatabase() throws IOException { 
     //Open your local db as the input stream 
     InputStream myinput = mycontext.getAssets().open("databases/" + DB_NAME); 

     // Path to the just created empty db 
     String outfilename = DB_PATH + DB_NAME; 

     //Open the empty db as the output stream 
     OutputStream myoutput = new FileOutputStream(outfilename); 

     // transfer byte to inputfile to outputfile 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myinput.read(buffer)) > 0) { 
      myoutput.write(buffer, 0, length); 
     } 

     //Close the streams 
     myoutput.flush(); 
     myoutput.close(); 
     myinput.close(); 
    } 

    public void opendatabase() throws SQLException { 
     //Open the database 
     String mypath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READONLY); 
    } 

    public synchronized void close() { 
     if (myDataBase != null) { 
      myDataBase.close(); 
     } 
     super.close(); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     if (newVersion > oldVersion) 
      try { 
       copydatabase(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
    } 
} 

エラーログ:

E/SQLiteLog: (1) no such table: Trigrams 
E/InputEventReceiver: Exception dispatching input event. 
E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback 
E/MessageQueue-JNI: android.database.sqlite.SQLiteException: no such table: Trigrams (code 1): , while compiling: SELECT third FROM Trigrams WHERE first='a' AND second ='baby' ORDER BY freq DESC LIMIT 0,3 
    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) 
    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889) 
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500) 
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588) 
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58) 
    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37) 
    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44) 
    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1355) 
    at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1294) 
    at com.chair49.sentimentkeyboard.analysis.NextWord.getNextWords(NextWord.java:38) 
    at com.chair49.sentimentkeyboard.SimpleIME.onKey(SimpleIME.java:125) 
    at android.inputmethodservice.KeyboardView.detectAndSendKey(KeyboardView.java:828) 
    at android.inputmethodservice.KeyboardView.repeatKey(KeyboardView.java:1371) 
    at android.inputmethodservice.KeyboardView.onModifiedTouchEvent(KeyboardView.java:1281) 
    at android.inputmethodservice.KeyboardView.onTouchEvent(KeyboardView.java:1214) 
    at android.view.View.dispatchTouchEvent(View.java:9337) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2432) 
    at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1746) 
    at android.app.Dialog.dispatchTouchEvent(Dialog.java:787) 
    at android.inputmethodservice.SoftInputWindow.dispatchTouchEvent(SoftInputWindow.java:93) 
    at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2393) 
    at android.view.View.dispatchPointerEvent(View.java:9557) 
    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4263) 
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4102) 
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3644) 
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3697) 
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3663) 
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3789) 
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3671) 
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3846) 
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3644) 
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3697) 
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3663) 
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3671) 
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3644) 
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5955) 
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5929) 
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5890) 
    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6058) 
    at android.view.InputEventReceiver.dispatchInputEvent(Inp 
07-14 14:12:42.161 14083-14083/com.chair49.sentimentkeyboard E/AndroidRuntime: FATAL EXCEPTION: main 
+0

? –

+0

私は間違っているかもしれない..しかし、私はonUpgradeが失敗していると信じています。データベースを開くopendatabase()を呼び出します。これはonUpgrade()を引き起こし、アセットフォルダからのコピーを試みます。しかし、あなたのデータベースはオープンされているので、書き込むことはできません。この方法では、あなたのアプリは古いデータベースを保持しています。 – W0rmH0le

+0

Trigramsというテーブルがありますか?スペルは正しいですか? –

答えて

0

私はあなたのデータベースが更新されていないと信じています。私はassetフォルダのデータベースを扱う同様の問題に直面した。 onUpdate中

ワークフロー:

あなたは(それが既に存在している)データベースを更新すると、次のメソッドが呼び出されます:

opendatabase()->SQLiteDatabase.openDatabase() 

これは、データベースを開き、また、onUpgrade()がトリガされます。あなたのonUpgrade()

は、あなたがしてみてください:あなたはこれがIOExceptionと、データベースが更新されない原因となるファイルminitest.db

に上書きすることはできません

onUpgrade()->copydatabase() 

ただし、データベースが開かれています。

IOExceptionを処理しているため、その例外は表示されませんでした。あなたのアプリを/アンインストール(または単にデータを削除)することができます

を確認する方法

。うまくいくと、データベースは修正されているようですが、更新中にテーブルが更新されなかった場合は失敗します。

データベース番号を4に更新してログメッセージを確認し、onUpgrade()が失敗していることを確認することもできます。

回避策

これは私が行う方法です:あなたはAndroidの `sqlite3`コマンドラインを使用して` .db`ファイルを開こうとするとどうなりますか

class DataBaseHelper extends SQLiteOpenHelper { 
    private boolean shouldBeUpdated; 

    public DataBaseHelper(Context context) throws IOException { 
     ... 
     shouldBeUpdated = false; 

     if (dbexist) { 
      System.out.println("Database exists"); 
      opendatabase(); 
     } else { 
      System.out.println("Database doesn't exist"); 
      createdatabase(); 
      opendatabase(); 
     } 
    } 

    public void opendatabase() throws SQLException { 
     String mypath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READONLY); 

     // CLOSE DATABASE BEFORE UPDATING IT 
     close(); 

     if(shouldBeUpdated) { 
      try { 
       copydatabase(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     if (newVersion > oldVersion) 
      shouldBeUpdated = true; 
    } 
} 
+0

これはそれを修正しました。ありがとうございました :) – user1762507

関連する問題