2011-01-18 11 views

ответ

36

cursor.getColumnIndex(String columnName) возвращает -1, если столбец не существует. Так что я бы в основном выполнить простой запрос типа «SELECT * FROM ххх LIMIT 0,1» и использовать курсор, чтобы определить, если столбец, вы ищете, существует

ИЛИ

вы можете попробовать для запроса столбец «SELECT FROM theCol ххх» и поймать исключение

+0

Вот что я думал, но я получаю SQLiteException не говоря «нет такой колонки: тест ». Я проверяю, находится ли столбец в таблице, а если нет, добавьте его. – Lunchbox

+0

Вы получаете исключение во время запроса или во время getColumnIndex? Если durig запрос: вы уверены, что не указываете столбец, который вы тестируете в запросе (не делайте «SELECT col FROM ...», а вместо этого выполняете «SELECT * FROM ..»)? в противном случае он выдает ошибку, о которой вы упоминаете, и вы должны ее поймать. – martinpelant

+0

Это происходит во время запроса. Я использую SQLiteQueryBuilder для создания запроса и поставки его с проекционной картой, которая охватывает столбцы в таблице. – Lunchbox

4

Я на самом деле написал эту функцию, которая, кажется, довольно чистый:

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 ; 
} 
29

Моя функция, основанная на @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"); 
+6

Вы должны закрыть курсор в блоке 'finally'! – WonderCsabo

3

Вот мое решение вопроса, который добавляет, чтобы флексо решение немного.

Вы можете поместить этот метод в любой класс, возможно, в ваш расширяемый класс 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(); 
    } 
} 
+1

Это выглядит намного чище, но я не уверен, что всегда хорошая идея закрыть базу данных. –

+1

Да, @ ban-geoengineering. Я не был уверен в этом, и поэтому я сказал закрыть его, только если вам это больше не нужно. – lwdthe1

2

Если вы используете 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; 
    } 
0

это мой код тестирования:

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+","); 
+0

для ActiveAndroid вы можете получить имя таблицы из класса с помощью этого кода: – Tom

+0

Cache.getTableInfo (type) .getTableName() – Tom

Смежные вопросы