2012-03-28 96 views
18

我開始進入SQLite和Android數據庫,我剛剛發現這個問題。我已經閱讀了很多類似的問題,但我還沒有找到解決方案。Android SQLite「沒有這樣的表」異常

這是我得到的錯誤:

E/AndroidRuntime(529):android.database.sqlite.SQLiteException:通過沒有造成這樣的表:ligas_bd:,編譯時:SELECT * FROM ligas_bd

這是我的代碼。

DBHelper myDbHelper = new DBHelper(this); 
myDbHelper = new DBHelper(this); 
try { 
    myDbHelper.createDataBase(); 
} catch (IOException ioe) { 
    throw new Error("Unable to create database"); 
} 
try { 
    myDbHelper.open(); 
    SQLiteDatabase db = null; 
    db = myDbHelper.getWritableDatabase(); 
    String[] args = new String[] {""}; 
    Cursor c = db.rawQuery(" SELECT * FROM ligas_bd", args); <---- Error in this line 
    if (c.moveToFirst()) { 
     do { 
      String cod = c.getString(0); 
      String nombre = c.getString(1); 
      String flag = c.getString(0); 
      String cod_url = c.getString(0); 
      ligas.add(new Item_Liga(nombre, flag, cod, cod_url)); 
     } while(c.moveToNext()); 
    } 
}catch(SQLException sqle){ 
    throw sqle; 
} 

DBHelper.java

public class DBHelper extends SQLiteOpenHelper{ 
private static String DB_NAME = "ligas_bd"; 
private SQLiteDatabase myDataBase; 
private final Context myContext; 

public DBHelper(Context context) { 
    super(context, DB_NAME, null, 1); 
    this.myContext = context; 
} 

public void createDataBase() throws IOException{ 
    boolean dbExist = checkDataBase(); 
    if(dbExist){ } 
    else { 
     this.getReadableDatabase(); 
     try { 
      copyDataBase(); 
     } catch (IOException e) { 
      throw new Error("Error copiando Base de Datos"); 
     } 
    } 
} 
private boolean checkDataBase(){ 
    SQLiteDatabase checkDB = null; 
    try { 
     String myPath = DB_PATH + DB_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
    } catch(SQLiteException e) { } 
    if(checkDB != null) { 
     checkDB.close(); 
    } 
    return checkDB != null ? true : false; 
} 

private void copyDataBase() throws IOException{ 
    InputStream myInput = myContext.getAssets().open(DB_NAME); 
    String outFileName = DB_PATH + DB_NAME; 
    OutputStream myOutput = new FileOutputStream(outFileName); 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = myInput.read(buffer))>0) { 
     myOutput.write(buffer, 0, length); 
    } 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 
} 

public void open() throws SQLException{ 
    try { 
     createDataBase(); 
    } catch (IOException e) { 
     throw new Error("Ha sido imposible crear la Base de Datos"); 
    } 
    String myPath = DB_PATH + DB_NAME; 
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
} 

@Override 
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) { } 

我也檢查了我的手機根本Explorer數據/數據/ mypackagename /數據庫和數據庫在那裏出現是正常的。

我的數據庫和主表具有相同的名稱,你可以在這個PIC SQLite數據庫瀏覽器中看到:

screen capture

我沒有創建表時,我使用SQLite數據庫之前創建它瀏覽器和我只是想讀取它


我不知道怎麼了,但我終於修好了。我剛剛開始,這次是this tutorial。 希望它有幫助!

+0

什麼是'DB_PATH'? – Squonk 2012-03-28 23:57:28

+0

是數據庫必須的路徑。它是/ data/data/mypackagename/databases – andoni90 2012-03-29 08:04:49

回答

16

這只是一種猜測,但我可以看到三種可能的事情發生在這裏...

  1. 呼喚你createDatabase()方法this.getReadableDatabase()會自動創建一個空數據庫。
  2. 您嘗試從assets文件夾複製預先創建的數據庫失敗或將數據庫複製到錯誤的地方。
  3. 在步驟1(上面)中創建的空數據庫是從主代碼調用db.rawQuery(...)時正在查詢的數據庫。

爲了進一步解釋這是usefult看源SQLiteOpenHelper

當您創建的SQLiteOpenHelper一個實例它設置之類的數據庫名稱和版本,但它不創建數據庫。相反,第一次調用getReadableDatabase()getWritableDatabase()會檢查數據庫是否存在,如果不存在,它會創建它。創建空數據庫後,將調用onCreate(...)方法,在您的情況下,它什麼都不做。

在第2點(上圖) - 你說DB_PATH/data/data/mypackagename/databases。如果真是這樣的話,你有沒有尾隨/後再行...

String myPath = DB_PATH + DB_NAME; 

...將設置myPath/data/data/mypackagename/databasesligas_db。在這種情況下,即使從assets複製成功,複製的數據庫也不會在您期望的位置。

最後在第3點(上圖)當您撥打db.rawQuery(...)時,db指向的實例由前面調用getWritableDatabase()返回。假設從assets複製失敗或它已被複制到不正確的路徑,db將指向在步驟1中創建的空數據庫。

您收到的錯誤是該表不存在,它是isn表示數據庫不存在的錯誤 - 唯一合乎邏輯的解釋是它在空數據庫上執行查詢,而不是從assets複製的數據庫。

編輯:我想說的另一件事。對任何Android目錄使用硬編碼路徑並不是一個好主意。例如 - 雖然在大多數設備上,創建數據庫的目錄將是/data/data/<package-name>/databases,但這不是保證。如果調用getDatabasePath(...)方法會更安全,因爲它將返回一個File對象,該對象可用於獲取Android數據庫類使用的數據庫目錄的路徑。

+0

+1。 :) – PhatHV 2012-03-30 06:24:06

+1

路徑是好的,最後有「/」,所以這不是錯誤。如果我更改路徑,則會拋出另一個異常,以便路徑正常,並且它正在正確查找數據庫。這是一件奇怪的事情 – andoni90 2012-03-30 12:26:50

+0

@koneX:在這種情況下,嘗試調用'File dbFile = getDatabasePath(「ligas_bd」)'並使用logcat記錄'dbFile'對象的路徑,或者使用'Toast'直接顯示它。在您的主代碼中調用'db.rawQuery(...)'之前立即執行此操作。這至少會向您顯示'SQLiteOpenHelper'用來訪問數據庫的路徑。 – Squonk 2012-03-30 15:52:56

1

唯一的例外是很清楚,你已經創建了在它(沒有這樣的表例外=沒有名爲ligas_db表)數據庫(ligas_db),但不是表

檢查:http://www.vogella.de/articles/AndroidSQLite/article.html

(ÊEres Antonio Recio?jaja)

+0

數據庫名稱和表名稱相同,請參閱編輯中上面的照片。謝謝(是的,沒有大豆Antonio Recio jajajajaja) – andoni90 2012-03-28 23:18:45

0

您有ligas_bd作爲數據庫的名稱,您正在嘗試從中SELECT

+0

數據庫和表具有相同的名稱,請參閱上面的帖子中的編輯。非常感謝 – andoni90 2012-03-28 23:19:57

0

您需要首先創建表格,然後再從中進行選擇。可能您之前已經創建過,但您需要在打開數據庫連接後創建它。

+0

我不知道你的意思。我在使用自己的編輯器之前創建了它,現在我必須在代碼中創建它?以及如何做到這一點? – andoni90 2012-03-30 13:29:26

+0

您正在使用:db = myDbHelper.getWritableDatabase(); 之後寫這段代碼來創建表如果不存在。或者在創建表語句之前打開數據庫連接。 – Dhruvisha 2012-03-30 13:53:41

+0

我想從現有的數據庫中獲取表格,我將其放置在資產文件夾中,我不想創建任何表 – andoni90 2012-03-30 14:24:19

15

我有同樣的問題,並通過清理項目和刪除我的測試設備上的應用程序並重新安裝它來解決它。我相信這是因爲我錯誤地跟着另一個創建了空數據庫的教程。更正後的代碼正在檢索舊的空數據庫。

+0

你先生,值得我付出更多的讚美。我也有這個錯誤,你的建議是解決了這個問題。謝謝!!!! – Salmononius2 2015-01-13 20:49:17

+0

在我的情況下,我不得不使用一個全新的模擬器,但這也是我的工作 – heLL0 2015-09-24 14:42:50

+0

最有可能的答案 – Zen 2016-03-05 01:28:26

0

我的問題是我離開「/ databases /」關閉我的路徑名稱的結尾。對於我來說,讓我感到困惑的是在加載dbconnection並將其存儲爲實例變量之前的代碼。然後,當我需要使用getReadableDatabase()和getWritableDatabase()方法時,他們一直拉動在「真實」數據庫路徑中創建的空數據庫。

不正確 /數據/數據/ mypackagename/

正確 /數據/數據/ mypackagename /數據庫/

+1到@Squonk誰的答案終於幫我跟蹤下來!

11

如果您在設備上運行您的應用程序,請轉到>>設置(在Android設備中)>>>應用程序>>>找到您的應用程序>>清除數據和緩存。在此之後,調試或重新安裝新的應用程序..

我通過這樣做,解決了這個問題...

0

我有同樣的問題,嘗試包括。db擴展名的文件名如:

private static String DB_NAME = "ligas_bd.db";