Android SQLite“没有这样的表”异常

新手上路,请多包涵

我开始研究 Android 中的 SQLite 和数据库,我刚刚发现了这个问题。我已经阅读了很多类似的问题,但我还没有找到解决方案。

这是我得到的错误:

E/AndroidRuntime(529): Caused by: android.database.sqlite.SQLiteException: no such table: 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) { }

我还使用 root explorer data/data/mypackagename/databases 检查了我的手机,数据库正常显示在那里。

我的数据库和主表同名,你可以在这张 SQLite 数据库浏览器图片中看到:

屏幕截图

我没有创建表,我在使用 SQLite 数据库浏览器之前创建了它,我只是想从中读取


我不知道怎么办,但我终于修好了。我刚刚重新开始,这次是按照 本教程。希望能帮助到你!

原文由 andoni90 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 817
2 个回答

这只是一个猜测,但我可以看到这里发生了三种可能的事情……

  1. 在您的 createDatabase() 方法中调用 this.getReadableDatabase() 会自动创建一个空数据库。
  2. 您尝试从 assets 文件夹复制预先创建的数据库失败或数据库被复制到错误的位置。
  3. 在步骤 1(上面)中创建的空数据库是您从主代码调用 db.rawQuery(...) 时要查询的数据库。

为了进一步解释,查看 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 中创建的空数据库。

您得到的错误是该表不存在并且它不是指示数据库不存在的错误 - 唯一合乎逻辑的解释是它正在对一个空数据库而不是从中复制的数据库执行查询 assets

编辑:我想提的另一件事。使用任何 Android 目录的硬编码路径都不是一个好主意。例如 - 虽然在大多数设备上,创建数据库的目录将是 /data/data/<package-name>/databases 这不是保证。如果您调用 getDatabasePath(...) 方法会更安全,因为它将返回一个 File 对象,该对象可用于获取 Android 数据库类使用的数据库目录的路径。

原文由 Squonk 发布,翻译遵循 CC BY-SA 3.0 许可协议

我遇到了同样的问题,并通过清理项目并从我的测试设备上删除应用程序并重新安装来解决它。我相信这是因为我按照另一个教程错误地创建了一个空数据库。更正后的代码正在检索旧的空数据库。

原文由 Logan 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题