2010-06-17 172 views
73

我有一个android应用程序,需要检查数据库中是否有记录,如果没有,处理一些事情并最终插入它,并且只要数据存在就从数据库中读取数据。我使用SQLiteOpenHelper的子类来创建并获取SQLiteDatabase的可重写实例,如果它不存在,我认为它会自动处理创建表(因为执行该操作的代码位于onCreate(...)中。 ) 方法)。但是,当表尚不存在,并且第一个方法运行在SQLiteDatabase对象上时,我有一个查询调用(...),我的logcat显示“I/Database(26434)”的错误: sqlite返回:错误代码= 1,msg =没有这样的表:appdata“,果然,appdata表没有被创建。如何检查Android SQLite数据库中是否存在表?

任何想法为什么?

我正在寻找一种方法来测试表是否存在(因为如果没有,数据当然不在其中,并且我不需要直到我写入它才能读取它,这看起来似乎创建正确的表),或一种方法来确保它被创建,并且仅仅是空的,在时间上为第一次调用查询(...)

编辑
这是后贴下面的两个答案:
我想我可能已经发现了这个问题。出于某种原因,我决定为每个表创建不同的SQLiteOpenHelper,即使它们都访问同一个数据库文件。我认为重构该代码只使用一个OpenHelper,并在其onCreate内创建两个表可能会更好...

回答

7

是的,原来在我编辑中的理论是正确的:导致onCreate方法不运行的问题是事实SQLiteOpenHelper对象应该引用数据库,并没有为每个表单独一个。将两个表格打包成一个SQLiteOpenHelper解决了这个问题。

+0

不错!谢谢你的工作 – Mayank 2015-01-08 05:22:14

44

我对Android SQLite API一无所知,但如果您能够直接在SQL中与它交谈,你可以这样做:

create table if not exists mytable (col1 type, col2 type); 

这将确保表总是被创建的,如果它已经存在,不会抛出任何错误。

+0

这就是我如何在SQLiteOpenHelper类中的onCreate方法创建表。在android中,建议让该类创建表,因为它允许应用程序自动更新其数据库,并且通常显然更高效。 不幸的是,执行代码非常类似于你所写的代码的代码块没有得到及时运行:( – camperdave 2010-06-17 05:18:16

+0

这很好,也适用于索引,即:“创建索引,如果不存在[...]”。 – 2013-07-22 18:43:43

+4

这实际上是问题的最佳答案 – 2016-04-05 03:00:28

2

您提到您已创建了一个扩展SQLiteOpenHelper并实施onCreate方法的类。你是否确定你正在执行与该类的所有数据库获取调用?您只能通过SQLiteOpenHelper#getWritableDatabasegetReadableDatabase获取SQLiteDatabase对象,否则在必要时将不会调用onCreate方法。如果您正在执行此操作,请检查是否正在调用SQLiteOpenHelper#onUpgrade方法。如果是这样,那么数据库版本号在某个时间点发生了变化,但是在发生这种情况时从未正确创建表。另外,您可以通过确保与数据库的所有连接都已关闭并调用Context#deleteDatabase,然后使用SQLiteOpenHelper为您提供新的数据库对象来强制重新创建数据库。

+0

嗯,我通过getWritableDatabase()调用获取数据库对象,对不起,我忘了指定它 另外, m确保onUpgrade()没有被调用,因为该方法有一个Log.d(...)调用作为我在数据库中没有看到的第一行,我会尝试删除整个数据库文件,并且我们会看看是否以某种方式修复它... – camperdave 2010-06-17 14:50:51

+0

不幸的是,删除整个数据库(我用root explorer来清除文件)没有 不行。我在我的应用程序中使用了两个表格 - 其中一个完美初始化,但另一个一直给我带来麻烦的却没有。 – camperdave 2010-06-17 14:54:51

0

no such table exists: error即将到来,因为一旦您创建数据库与一个表之后,每当你在同一个数据库中创建表,它会给出此错误。

要解决此错误,您必须创建新数据库并在onCreate()方法内部可以在同一数据库中创建多个表。

9

这是我做过什么:

/* 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; 
109

试试这个:

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; 
} 
+0

非常感谢。很棒。 +1 – Gray 2012-01-18 03:44:47

+1

大帮忙!谢谢。 – 2012-01-18 18:43:13

+9

不要忘记'cursor.close();' – styler1972 2012-05-07 21:31:28

10

尽管目前已经有很多很好的回答这个问题,我想出了另一种解决方案,我认为更简单。围绕您的查询尝试块和以下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. 
    } 
} 

它为我工作!

+1

将if语句放在if()块中不是更好吗?它看起来像SQLiteException由于另一个原因而不是“没有这样的表”引发,日志将表明你正在创建表,而实际上不是。 – 2012-08-23 08:37:38

+0

你是对的......很好! – robguinness 2012-08-23 09:45:27

-1

..... 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 

.....

0
// @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_MASTER表。
  • 所以在这里我们只是简单地在它上面运行SELECT命令,如果表存在的话,我们会得到游标数为1。
+1

考虑提供对您的代码的解释 – arghtype 2015-07-11 14:31:14

0
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; 
} 
相关问题