安卓SQLite "无此表 "异常[英] Android SQLite "no such table" exception

本文是小编为大家收集整理的关于安卓SQLite "无此表 "异常的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我开始使用 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) { }

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

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

屏幕截图

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

<小时>

我不知道怎么弄,但我终于修好了.我刚刚重新开始,这次是按照 本教程.希望有帮助!

推荐答案

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

  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 数据库类使用的数据库目录的路径.

其他推荐答案

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

其他推荐答案

如果您正在设备中运行您的应用,请转到>>设置(在Android设备中)>>>应用程序>>>找到您的应用程序>>清除数据和缓存.之后,再次调试或安装您的新应用程序..

我通过这样做解决了这个问题...

本文地址:https://www.itbaoku.cn/post/597546.html

问题描述

I'm starting into SQLite and databases in Android and I just found this issue. I have read a lot of similar questions but I have not found a solution yet.

This is the error I'm getting:

E/AndroidRuntime(529): Caused by: android.database.sqlite.SQLiteException: no such table: ligas_bd: , while compiling: SELECT * FROM ligas_bd

This is my code.

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

I also checked in my phone with root explorer data/data/mypackagename/databases and the database appears there as normal.

My database and the main table have the same name, as you can see in this pic of SQLite database browser:

screen capture

I am not creating the table, I created it before using SQLite Database Browser and I am just trying to read from it


I don't know how, but I finally fixed it. I just started again, this time following this tutorial. Hope it helps!

推荐答案

This is only a guess but I can see three possible things are happening here...

  1. Calling this.getReadableDatabase() in your createDatabase() method is automatically creating an empty database.
  2. Your attempt to copy your pre-created database from your assets folder is failing or the database is being copied to the wrong place.
  3. The empty database created in step 1 (above) is the one that is being queried when you call db.rawQuery(...) from your main code.

To explain further it is usefult to look at the source for SQLiteOpenHelper

When you create an instance of SQLiteOpenHelper it sets things like the database name and version but it does not create the database. Instead, the first call to either getReadableDatabase() or getWritableDatabase() checks to see if the database exists and if it doesn't it creates it. After creating the empty database, the onCreate(...) method is called which, in your case, does nothing.

On to point 2 (above) - you say that DB_PATH is /data/data/mypackagename/databases. If that is really the case and you have no trailing / then the line...

String myPath = DB_PATH + DB_NAME;

...will set myPath to /data/data/mypackagename/databasesligas_db. In that case, even if the copy from assets succeeds, the copied database isn't going to be where you expect it to be.

Finally on point 3 (above) when you call db.rawQuery(...) the instance that db points to is returned by the previous call to getWritableDatabase(). Assuming the copy from assets has failed or that it has been copied to the incorrect path, db will be pointing at the empty database created in step 1.

The error you get is that the table doesn't exist and it isn't an error indicating the database doesn't exist - the only logical explanation is that it's performing a query on an empty database and not the one that has been copied from assets.

EDIT: One other thing I meant to mention. It isn't a good idea to use hard-coded paths to any of the Android directories. For example - although on most devices, the directory where databases are created will be /data/data/<package-name>/databases this is not a guarantee. It is much safer if you call the getDatabasePath(...) method as it will return a File object which can be used to get the path to the databases directory used by the Android database classes.

其他推荐答案

I had the same problem and fixed it by cleaning the project and deleting the app off my testing device and reinstalling it. I believe it occurred because I followed another tutorial that created an empty database by mistake. The corrected code was retrieving the old empty database.

其他推荐答案

If you are running your app in your device, go to >>Settings (in Android device)>>>application>>>locate your application>>clear data and cache. After that, debug or install again your new application..

I solved this problem by doing that...