2011-01-18 22 views

Respuesta

36

cursor.getColumnIndex(String columnName) devuelve -1 si, la columna no existe. Así que básicamente realizar una consulta simple como "SELECT * FROM 0,1 xxx LIMIT" y utilizar el cursor para determinar si la columna, que está buscando, existe

O

se puede tratar de consultar la la columna "SELECT theCol de XXX" y coger una excepción

+0

Eso es lo que pensaba, pero estoy recibiendo un SQLiteException diciendo "no hay tal columna: test ". Estoy revisando para ver si la columna está en la tabla y si no, luego lo inserto. – Lunchbox

+0

¿recibe la excepción durante la consulta o durante getColumnIndex? Si durig la consulta: ¿está seguro de que no especifica la columna que prueba en la consulta (no haga "SELECCIONAR col FROM ..." sino que realice "SELECT * FROM ..." en su lugar)? de lo contrario, arroja el error que está mencionando y debe atraparlo. – martinpelant

+0

Ocurre durante la consulta. Estoy usando SQLiteQueryBuilder para crear la consulta y proporcionarle un mapa de proyección que abarca las columnas de la tabla. – Lunchbox

4

hecho, me escribió esta función que parece bastante limpio:

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

me llaman así:

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

Mi función basada en @martinpelants responder:

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(); 
    } 
} 

sólo tiene que llamar:

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

¡Debe cerrar el cursor en un bloque 'finally'! – WonderCsabo

3

Aquí está mi solución al problema que se suma a la solución un poco de flexo.

Puede poner este método en cualquier clase, tal vez su clase SQLiteOpenHelper que se extiende.

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

Esto se ve mucho más limpio, pero no estoy seguro de que siempre sea una buena idea cerrar la base de datos. –

+1

Yeah @ ban-geoengineering No estaba seguro de eso y es por eso que dije que lo cerrara solo si ya no lo necesita. – lwdthe1

2

Si utiliza 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

este es mi código de prueba:

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

para ActiveAndroid puede obtener el nombre de la tabla de clase con este código: – Tom

+0

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

Cuestiones relacionadas