代码之家  ›  专栏  ›  技术社区  ›  camperdave

如何检查android sqlite数据库中是否存在表?

  •  80
  • camperdave  · 技术社区  · 15 年前

    我有一个Android应用程序需要检查数据库中是否已经有记录,如果没有,处理一些事情并最终插入,如果数据确实存在,只需从数据库中读取数据。我正在使用sqliteOpenHelper的子类创建和获取sqliteDatabase的可重写实例,我认为如果表不存在,它会自动处理创建表的工作(因为要执行此操作的代码在onCreate(…)方法中)。

    但是,当表尚不存在,并且在我拥有的sqliteDatabase对象上运行的第一个方法是调用query(…)时,我的logcat显示一个错误“i/database(26434):sqlite返回:错误代码=1,msg=no such table:appdata”,并且确信没有创建appdata表。

    有什么想法吗?

    我正在寻找一种方法来测试表是否存在(因为如果不存在,那么数据肯定不在其中,并且在我写入它之前,我不需要读取它,这似乎可以正确地创建表),或者一种方法来确保它被创建,并且是空的,以便第一次调用查询(…)

    编辑
    这是在以下两个答案之后发布的:
    我想我可能发现了问题。出于某种原因,我决定为每个表创建不同的sqliteOpenHelper,即使两个表都访问相同的数据库文件。我认为将代码重构为只使用一个OpenHelper,并在其OnCreate中创建两个表可能会更好…

    10 回复  |  直到 8 年前
        1
  •  116
  •   Nikolay DS    13 年前

    试试这个:

    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;
    }
    
        2
  •  46
  •   chrisbtoo    15 年前

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

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

    这将确保始终创建表,并且如果表已经存在,则不会引发任何错误。

        3
  •  10
  •   Shabbir Dhangot    8 年前

    虽然这个问题已经有了很多好的答案,但我提出了另一个我认为更简单的解决方案。用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.
        }
    }
    

    对我有用!

        4
  •  9
  •   Nate    12 年前

    我就是这样做的:

    /* 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;
    
        5
  •  8
  •   camperdave    15 年前

    是的,事实证明我编辑的理论是正确的:导致onCreate方法不能运行的问题是 SQLiteOpenHelper 对象应该引用数据库,而不是为每个表单独引用一个数据库。把两张桌子打包成一张 存取资料表 解决了问题。

        6
  •  2
  •   Rich Schuler    15 年前

    您提到您已经创建了一个扩展 SQLiteOpenHelper 并实施了 onCreate 方法。您确定要用这个类执行所有的数据库获取调用吗?你应该只得到 SQLiteDatabase 对象通过 SQLiteOpenHelper#getWritableDatabase getReadableDatabase 否则 创建时的回调函数 必要时将不调用方法。如果你已经这样做了,检查一下 SQLiteOpenHelper#onUpgrade 正在改为调用方法。如果是这样,那么数据库版本号在某个时间点被更改了,但在发生这种情况时,表从未被正确创建。

    另外,您可以通过确保与数据库的所有连接都已关闭并调用来强制重新创建数据库。 Context#deleteDatabase 然后使用 存取资料表 给你一个新的数据库对象。

        7
  •  2
  •   gtzinos    9 年前
     // @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_主表,其中包含数据库中所有表和索引的信息。
    • 所以这里我们只是在它上面运行select命令,如果表存在,我们将得到计数为1的光标。
        8
  •  0
  •   Yogesh Rathi    8 年前
     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;
    }
    
        9
  •  0
  •   Jéwôm'    8 年前

    no such table exists: error 即将到来,因为一旦用一个表创建了数据库,之后每当在同一个数据库中创建表时,都会出现此错误。

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

        10
  •  -1
  •   Srinath Ganesh    12 年前

    … toast t=toast.maketext(上下文,“Try…”,吐司,长度短; T)();

        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