Android SQLite“没有这样的表”例外 [英] Android SQLite "no such table" exception

查看:128
本文介绍了Android SQLite“没有这样的表”例外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是我得到的错误:


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


这是我的代码。

  DBHelper myDbHelper = new DBHelper(this); 
myDbHelper = new DBHelper(this);
try {
myDbHelper.createDataBase();
} catch(IOException ioe){
throw new Error(无法创建数据库);
}
try {
myDbHelper.open();
SQLiteDatabase db = null;
db = myDbHelper.getWritableDatabase();
String [] args = new String [] {};
Cursor c = db.rawQuery(SELECT * FROM ligas_bd,args); < ----此行中的错误
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上下文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);
}
}
}
私人布尔值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?真假;
}

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 /数据库和数据库出现在正常。



我的数据库和主表有相同的名称,你可以看到在这个图片的SQLite数据库浏览器: p>



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






我不知道如何,但我终于解决了。我刚重新开始,这次是本教程
希望它帮助!

解决方案

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


  1. 中调用 this.getReadableDatabase()

  2. 您尝试从资产中复制预创建的数据库文件夹失败或数据库正在复制到错误的位置。

  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 的副本成功,复制的数据库也不会在您预期的位置。



最后,当你调用 db.rawQuery(...)的实例 db 指向由之前调用 getWritableDatabase()返回的。假设来自 assets 的副本失败或者它已被复制到不正确的路径, db 将指向在步骤1中创建的空数据库。



您得到的错误是表不存在,并不是指示数据库不存在的错误 - 只有逻辑的解释是,它对空数据库执行查询,而不是从 assets 复制的查询。



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


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:

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.

这篇关于Android SQLite“没有这样的表”例外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆