[英]How does one check if a table exists in an Android SQLite database?
我有一个android应用程序需要检查数据库中是否已经有记录,如果没有,处理一些事情并最终插入它,如果数据确实存在,只需从数据库中读取数据。 我正在使用 SQLiteOpenHelper 的子类来创建和获取 SQLiteDatabase 的可重写实例,我认为如果它不存在,它会自动负责创建表(因为执行此操作的代码在 onCreate(... ) 方法)。
但是,当表尚不存在,并且在我拥有的 SQLiteDatabase 对象上运行的第一个方法是对 query(...) 的调用时,我的 logcat 显示错误“I/Database(26434):sqlite 返回:错误code = 1, msg = no such table: appdata",果然没有创建 appdata 表。
关于为什么的任何想法?
我正在寻找一种方法来测试表是否存在(因为如果不存在,则数据肯定不在其中,并且在写入之前我不需要读取它,这似乎创建了表正确),或者确保它被创建并且是空的,及时第一次调用 query(...)
编辑
这是在以下两个答案之后发布的:
我想我可能已经发现了问题。 我出于某种原因决定应该为每个表创建一个不同的 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);
这将确保该表始终被创建并且如果它已经存在则不会抛出任何错误。
虽然这个问题已经有很多很好的答案了,但我想出了另一个我认为更简单的解决方案。 用 try 块和以下捕获包围您的查询:
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
解决了这个问题。
您提到您已经创建了一个扩展SQLiteOpenHelper
的类并实现了onCreate
方法。 您是否确保使用该类执行所有数据库获取调用? 您应该只通过SQLiteOpenHelper#getWritableDatabase
和getReadableDatabase
获取SQLiteDatabase
对象,否则在必要时将不会调用onCreate
方法。 如果您已经这样做了,请检查并查看是否正在调用SQLiteOpenHelper#onUpgrade
方法。 如果是这样,则数据库版本号在某个时间点发生了更改,但在发生这种情况时从未正确创建表。
Context#deleteDatabase
,您可以通过确保关闭所有连接并调用Context#deleteDatabase
然后使用SQLiteOpenHelper
为您提供新的 db 对象来SQLiteOpenHelper
重新创建数据库。
// @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;
}
Kotlin 解决方案,基于其他人在这里写的内容:
fun isTableExists(database: SQLiteDatabase, tableName: String): Boolean {
database.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '$tableName'", null)?.use {
return it.count > 0
} ?: return false
}
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;
}
重要的条件是IF NOT EXISTS检查表在数据库中是否已经存在
喜欢...
String query = "CREATE TABLE IF NOT EXISTS " + TABLE_PLAYER_PHOTO + "("
+ KEY_PLAYER_ID + " TEXT,"
+ KEY_PLAYER_IMAGE + " TEXT)";
db.execSQL(query);
我面对这个问题并通过 try catch 处理它,就像我在表中做我想做的一样简单,如果它不存在会导致错误,所以通过异常捕获它并创建它:)
SQLiteDatabase db=this.getWritableDatabase();
try{
db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations");
db.execSQL("DELETE FROM vacations");
}catch (SQLiteException e){
db.execSQL("create table o_vacations (id integer primary key ,name text ,vacation text,date text,MONTH text)");
db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations");
db.execSQL("DELETE FROM vacations");
}
no such table exists: error
即将发生,因为一旦您创建带有一张表的数据库,那么每当您在同一数据库中创建表时,都会出现此错误。
要解决此错误,您必须创建新数据库,并且在 onCreate() 方法中,您可以在同一个数据库中创建多个表。
..... 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
.....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.