我有一个Android应用程序,需要检查数据库中是否已有记录,如果没有,处理一些事情并最终插入它,如果数据确实存在,只需从数据库中读取数据.我正在使用SQLiteOpenHelper的子类来创建和获取SQLiteDatabase的可重写实例,我认为如果它还不存在,我认为它会自动创建表(因为代码要在onCreate中执行(... ) 方法).
但是,当表尚不存在,并且第一个方法运行SQLiteDatabase对象时,我有一个调用查询(...),我的logcat显示错误"我/数据库(26434):sqlite返回:错误code = 1,msg =没有这样的表:appdata",果然,appdata表没有被创建.
有什么想法吗?
我正在寻找一种方法来测试表是否存在(因为如果不存在,数据肯定不在其中,我不需要读它,直到我写它,这似乎创建表正确的),或者确保它被创建的方法,并且只是空的,及时进行第一次查询调用(...)
编辑
这是在以下两个答案之后发布的:
我想我可能已经找到了问题.我出于某种原因决定为每个表创建一个不同的SQLiteOpenHelper,即使它们都访问相同的数据库文件.我认为重构该代码只使用一个OpenHelper,并在其中创建两个表onCreate可能会更好...
试试这个:
public boolean isTableExists(String tableName, boolean openDb) { if(openDb) { if(mDatabase == null || !mDatabase.isOpen()) { mDatabase = getReadableDatabase(); } if(!mDatabase.isReadOnly()) { mDatabase.close(); mDatabase = getReadableDatabase(); } } String query = "select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'"; try (Cursor cursor = mDatabase.rawQuery(query, null)) { if(cursor!=null) { if(cursor.getCount()>0) { return true; } } return false; } }
我对Android SQLite API一无所知,但是如果你能直接在SQL中与它交谈,你可以这样做:
create table if not exists mytable (col1 type, col2 type);
这将确保始终创建表,并且如果已经存在则不会抛出任何错误.
这就是我做的:
/* open database, if doesn't exist, create it */
SQLiteDatabase mDatabase = openOrCreateDatabase("exampleDb.db", SQLiteDatabase.CREATE_IF_NECESSARY,null);
Cursor c = null;
boolean tableExists = false;
/* get cursor on it */
try
{
c = mDatabase.query("tbl_example", null,
null, null, null, null, null);
tableExists = true;
}
catch (Exception e) {
/* fail */
Log.d(TAG, tblNameIn+" doesn't exist :(((");
}
return tableExists;
虽然这个问题已经有很多好的答案,但我想出了另一个我认为更简单的解决方案.使用try块和以下catch来查询查询:
catch (SQLiteException e){ if (e.getMessage().contains("no such table")){ Log.e(TAG, "Creating table " + TABLE_NAME + "because it doesn't exist!" ); // create table // re-run query, etc. } }
它对我有用!
是的,在我的编辑中证明理论是正确的:导致onCreate方法不运行的问题是SQLiteOpenHelper
对象应该引用数据库,而不是每个表都有一个单独的数据库.将两个表打包成一个SQLiteOpenHelper
解决了问题.