【问题标题】:Checking if a column exists in an application database in Android检查Android中的应用程序数据库中是否存在列
【发布时间】:2011-01-18 01:10:18
【问题描述】:

在 Android 中是否有一种很好的方法来查看应用程序数据库的表中是否存在列? (我知道已经有类似的问题,但似乎没有任何特定于 Android 的问题。)

【问题讨论】:

    标签: android database sqlite


    【解决方案1】:

    cursor.getColumnIndex(String columnName) 如果该列不存在,则返回 -1。所以我基本上会执行一个简单的查询,比如“SELECT * FROM xxx LIMIT 0,1”,并使用光标来确定你正在寻找的列是否存在

    您可以尝试查询“SELECT theCol FROM xxx”列并捕获异常

    【讨论】:

    • 这就是我的想法,但我得到一个 SQLiteException 说“没有这样的列:测试”。我正在检查该列是否在表中,如果没有,则插入它。
    • 您是在查询期间还是在 getColumnIndex 期间遇到异常?如果在查询期间:您确定您没有指定您在查询中测试的列(不要执行“SELECT col FROM ...”而是执行“SELECT * FROM..”)?否则它会抛出你提到的错误,你必须抓住它。
    • 在查询期间发生。我正在使用 SQLiteQueryBuilder 来构建查询并为其提供跨越表中列的投影图。
    • 试试 SQLiteDatabase.rawQuery("SELECT * FROM table LIMIT 0,1", null);而不是使用构建器
    • 我想我应该提到我在那个查询中也有一个 WHERE 子句。我删除了该子句并获得了成功的查询。您的解决方案有效!谢谢。
    【解决方案2】:

    我的函数基于@martinpelants 的回答:

    private boolean existsColumnInTable(SQLiteDatabase inDatabase, String inTable, String columnToCheck) {
        Cursor mCursor = null;
        try {
            // Query 1 row 
            mCursor = inDatabase.rawQuery("SELECT * FROM " + inTable + " LIMIT 0", null);
    
            // getColumnIndex() gives us the index (0 to ...) of the column - otherwise we get a -1
            if (mCursor.getColumnIndex(columnToCheck) != -1)
                return true;
            else
                return false;
    
        } catch (Exception Exp) {
            // Something went wrong. Missing the database? The table?
            Log.d("... - existsColumnInTable", "When checking whether a column exists in the table, an error occurred: " + Exp.getMessage());
            return false;
        } finally {
            if (mCursor != null) mCursor.close();
        }
    }
    

    只需调用:

    boolean bla = existsColumnInTable(myDB,"MyTable","myColumn2check");
    

    【讨论】:

    • 您应该在finally 块中关闭光标!
    【解决方案3】:

    我实际上写了这个看起来很干净的函数:

    private boolean field_exists( String p_query )
    {
        Cursor mCursor  = mDb.rawQuery( p_query, null );
    
        if  (  ( mCursor != null ) && ( mCursor.moveToFirst()) )
        {
            mCursor.close();
            return true ;
        }
    
        mCursor.close();
        return false ;
    }
    

    我这样称呼它:

    if  ( field_exists( "select * from sqlite_master "              
        + "where name = 'mytable' and sql like '%myfield%' " ))
    {
        do_something ;
    }
    

    【讨论】:

      【解决方案4】:

      这是我对这个问题的解决方案,它稍微增加了柔印的解决方案。

      您可以将此方法放在任何类中,也许是您的 SQLiteOpenHelper 扩展类。

      public static boolean columnExistsInTable(SQLiteDatabase db, String table, String columnToCheck) {
          Cursor cursor = null;
          try {
              //query a row. don't acquire db lock
              cursor = db.rawQuery("SELECT * FROM " + table + " LIMIT 0", null);
      
              // getColumnIndex()  will return the index of the column 
              //in the table if it exists, otherwise it will return -1
              if (cursor.getColumnIndex(columnToCheck) != -1) {
                  //great, the column exists
                  return true;
              }else {
                  //sorry, the column does not exist
                  return false;
              }
      
          } catch (SQLiteException Exp) {
              //Something went wrong with SQLite. 
              //If the table exists and your query was good,
              //the problem is likely that the column doesn't exist in the table.
              return false;
          } finally {
              //close the db  if you no longer need it
              if (db != null) db.close();
              //close the cursor 
              if (cursor != null) cursor.close();
          }
      }
      

      【讨论】:

      • 这看起来更干净了,但我不确定关闭数据库是否总是一个好主意。
      • 是的@ban-geoengineering 我不确定,这就是为什么我说只有在你不再需要它时才关闭它。
      • 光标成功关闭任何返回(对于那些有疑问的人,比如我)
      【解决方案5】:

      如果你使用 ActiveAndroid

      public static boolean createIfNeedColumn(Class<? extends Model> type, String column) {
              boolean isFound = false;
              TableInfo tableInfo = new TableInfo(type);
      
              Collection<Field> columns = tableInfo.getFields();
              for (Field f : columns) {
                  if (column.equals(f.getName())) {
                      isFound = true;
                      break;
                  }
              }
              if (!isFound) {
                  ActiveAndroid.execSQL("ALTER TABLE " + tableInfo.getTableName() + " ADD COLUMN " + column + " TEXT;");
              }
              return isFound;
          }
      

      【讨论】:

        【解决方案6】:

        这是我的测试代码:

        String neadle = "id"; //searched field name
        String tableName = "TableName";
        boolean found = false;
        
        SQLiteDatabase mDb = ActiveAndroid.getDatabase();
        Cursor mCursor  = mDb.rawQuery( "SELECT * FROM sqlite_master WHERE name = '"+tableName+"' and sql like '%"+neadle+"%'" , null);
        mCursor.moveToFirst();
        String fie = ",";
        
        if (mCursor.getCount() > 0) {
            String[] fields = mCursor.getString(mCursor.getColumnIndex("sql")).split(",");
            for (String field: fields) {
                String[] fieldNameType = field.trim().split(" ");
                if (fieldNameType.length > 0){
                    fie += fieldNameType[0]+",";
                }
            }
        }else {
            //table not exist!
        }
        if (mCursor != null) mCursor.close();
        // return result: 
        found = fie.contains(","+neadle+",");
        

        【讨论】:

        • 对于 ActiveAndroid,您可以使用以下代码从类中获取表名:
        • Cache.getTableInfo(type).getTableName()
        【解决方案7】:

        冒着发布相同解决方案但更短的风险。这是基于@flexo 的精简版

          private boolean doesColumnExistInTable(SupportSQLiteDatabase db, String tableName, String columnToCheck) {
                try (Cursor cursor = db.query("SELECT * FROM " + tableName + " LIMIT 0", null)) {
                    return cursor.getColumnIndex(columnToCheck) != -1;
                } catch (Exception Exp) {
                    // Something went wrong. we'll assume false it doesn't exist
                    return false;
                }
            }
        

        在 Kotlin 中

          private fun doesColumnExistInTable(db: SupportSQLiteDatabase, tableName: String, columnToCheck: String): Boolean {
                try {
                    db.query("SELECT * FROM $tableName LIMIT 0", null).use { cursor -> return cursor.getColumnIndex(columnToCheck) != -1 }
                } catch (e: Exception) {
                    // Something went wrong. we'll assume false it doesn't exist
                    return false
                }
            }
        

        【讨论】:

        • columnToCheck 是什么?请
        • @AbdullahZakhoi columnToCheck 是我想检查它是否存在/存在于表中的列的字符串名称。
        猜你喜欢
        • 2018-08-26
        • 1970-01-01
        • 2021-11-30
        • 2016-01-10
        • 1970-01-01
        • 2020-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多