How does one check if a table exists in an Android SQLite database?
我有一个Android应用程序,需要检查数据库中是否已有记录,如果没有,处理一些事情并最终插入它,如果数据确实存在,只需从数据库中读取数据。我正在使用SQLiteOpenHelper的子类来创建和获取SQLiteDatabase的可重写实例,我认为如果它还不存在,我认为它会自动创建表(因为代码要在onCreate中执行(... ) 方法)。
但是,当表尚不存在,并且第一个方法运行SQLiteDatabase对象时,我有一个调用查询(...),我的logcat显示错误"我/数据库(26434):sqlite返回:错误code = 1,msg =没有这样的表:appdata",果然,appdata表没有被创建。
有什么想法吗?
我正在寻找一种方法来测试表是否存在(因为如果不存在,数据肯定不在其中,我不需要读它,直到我写它,这似乎创建表正确的),或者确保它被创建的方法,并且只是空的,及时进行第一次查询调用(...)
编辑
这是在以下两个答案之后发布的:
我想我可能已经发现了这个问题。我出于某种原因决定为每个表创建一个不同的SQLiteOpenHelper,即使它们都访问相同的数据库文件。我认为重构该代码只使用一个OpenHelper,并在其中创建两个表onCreate可能会更好...
试试这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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中与它交谈,你可以这样做:
1 | create table if not exists mytable (col1 type, col2 type); |
这将确保始终创建表,并且如果已经存在则不会抛出任何错误。
这就是我做的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* 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来查询查询:
1 2 3 4 5 6 7 | 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方法不运行的问题是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // @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的游标。
您提到您已经创建了一个扩展
另外,您可以通过确保关闭数据库的所有连接并调用
重要条件是IF NOT EXISTS检查表是否已存在于数据库中
喜欢...
1 2 3 4 | String query ="CREATE TABLE IF NOT EXISTS" + TABLE_PLAYER_PHOTO +"(" + KEY_PLAYER_ID +" TEXT," + KEY_PLAYER_IMAGE +" TEXT)"; db.execSQL(query); |
1 2 3 4 5 6 7 8 9 10 11 | 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; } |
要解决此错误,您必须创建新数据库,并且在onCreate()方法中,您可以在同一数据库中创建多个表。
.....
Toast t = Toast.makeText(context,"try ...",Toast.LENGTH_SHORT);
t.show();
1 2 3 4 5 6 7 8 9 | 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 |
.....