2012-03-28 100 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";