如何检查Android SQLite数据库中是否存在表?
我有一个android应用程序,需要检查数据库中是否有logging,如果没有,处理一些事情并最终插入它,如果数据存在,只需从数据库中读取数据。 我使用SQLiteOpenHelper的子类来创build并获得一个SQLiteDatabase的可重写实例,我认为自动照顾创build该表,如果它不存在(因为要做的代码是在onCreate(… ) 方法)。
但是,当表尚不存在,第一种方法运行SQLiteDatabase对象我有一个调用查询(…),我的logcat显示错误“我/数据库(26434):sqlite返回:错误代码= 1,味精=没有这样的表:appdata“,果然,没有创buildappdata表。
任何想法为什么?
我正在寻找一种方法来testing表是否存在(因为如果不存在,数据当然不在其中,我不需要读取它,直到我写入它,这似乎创build表正确),或确保它被创build的方式,只是空的,及时的第一次调用查询(…)
编辑
这是后面的两个答案发布:
我想我可能已经find了问题。 由于某种原因,我决定为每个表创build一个不同的SQLiteOpenHelper,尽pipe它们都访问同一个数据库文件。 我认为重构该代码只使用一个OpenHelper,并创build两个表内的onCreate可能会更好地工作…
试试这个:
public boolean isTableExists(String tableName, boolean openDb) { if(openDb) { if(mDatabase == null || !mDatabase.isOpen()) { mDatabase = getReadableDatabase(); } if(!mDatabase.isReadOnly()) { mDatabase.close(); mDatabase = getReadableDatabase(); } } Cursor cursor = mDatabase.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'", null); if(cursor!=null) { if(cursor.getCount()>0) { cursor.close(); return true; } cursor.close(); } return false; }
我对Android SQLite API一无所知,但是如果您可以直接在SQL中与之交谈,则可以这样做:
create table if not exists mytable (col1 type, col2 type);
这将确保表总是被创build,如果它已经存在,不会抛出任何错误。
虽然这个问题已经有很多很好的答案,但我想出了另一个我认为更简单的解决scheme。 围绕你的查询与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. } }
它为我工作!
这就是我所做的:
/* 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;
是的,原来在我的编辑理论是正确的:导致onCreate方法不运行的问题是SQLiteOpenHelper
对象应该引用数据库,并没有一个单独的每个表的事实。 将两个表打包成一个SQLiteOpenHelper
解决了这个问题。
您提到您创build了一个扩展SQLiteOpenHelper
并实现了onCreate
方法的类。 你确定你正在执行你所有的数据库与该类的电话吗? 您应该只能通过SQLiteOpenHelper#getWritableDatabase
和getReadableDatabase
获取SQLiteDatabase
对象,否则在必要时将不会调用onCreate
方法。 如果您正在执行此操作,请检查是否正在调用SQLiteOpenHelper#onUpgrade
方法。 如果是这样,那么数据库版本号在某个时间点被更改,但是在发生这种情况时从未正确创build表。
Context#deleteDatabase
,你可以通过确保所有的连接都被closures并调用Context#deleteDatabase
,然后使用SQLiteOpenHelper
给你一个新的db对象来SQLiteOpenHelper
重新创build数据库。
// @param db, readable database from SQLiteOpenHelper public boolean doesTableExist(SQLiteDatabase db, String tableName) { Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null); if (cursor != null) { if (cursor.getCount() > 0) { cursor.close(); return true; } cursor.close(); } return false; }
- sqlite维护包含数据库中所有表和索引信息的sqlite_master表。
- 所以在这里我们只是简单地在它上面运行SELECT命令,如果表存在,我们将得到游标数为1。
public boolean isTableExists(String tableName) { boolean isExist = false; Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null); if (cursor != null) { if (cursor.getCount() > 0) { isExist = true; } cursor.close(); } return isExist; }
no such table exists: error
即将到来,因为一旦您创build数据库与一个表之后,每当你在同一个数据库中创build表,它会给出这个错误。
要解决这个错误,你必须创build新的数据库,并且在onCreate()方法中你可以在同一个数据库中创build多个表。
….. Toast t = Toast.makeText(context,“try …”,Toast.LENGTH_SHORT); t.show();
Cursor callInitCheck = db.rawQuery("select count(*) from call", null); Toast t2a = Toast.makeText(context, "count rows " + callInitCheck.getCount() , Toast.LENGTH_SHORT); t2a.show(); callInitCheck.moveToNext(); if( Integer.parseInt( callInitCheck.getString(0)) == 0) // if no rows then do { // if empty then insert into call
…..