2012-01-27 19 views
6

Mientras trabajaba con SQLiteCursor en Android llegué a conocer que el getColumnIndex() se comporta de mayúsculas y minúsculas, por ejemplo:Android - Cursor SQLite getColumnIndex() distingue entre mayúsculas y minúsculas?

Ejemplo:

Column Name in DB was: Rules 
cursor.getColumnIndex("Rules") //workes fine 
cursor.getColumnIndex("rules") //throws error, see the error detail 

La documentación no dice nada acerca de que, por detalleplease see this.

LogCat dice:

java.lang.IllegalStateException: No se pudo leer la fila 0, columna de -1 CursorWindow. Asegúrese de que el cursor se ha inicializado correctamente antes acceso a los datos de que

Estoy confundido por este comportamiento de SQLiteCursor, alguien me puede ayudar a que esto es verdad o estoy haciendo algo mal? Puedo proporcionar el código si es necesario.

Gracias.

+1

Entonces, ¿cuál es su pregunta? –

+0

Por favor vea mi pregunta ahora. –

Respuesta

3

getColumnIndex() es sensible a mayúsculas:

Nombre de la columna en el PP era: Reglas

cursor.getColumnIndex ("Reglas ") // workes bien

cursor.getColumnIndex ("reglas") // lanza de error, ver el detalle de error

+4

No puedo imaginar por qué en la Tierra no normalizarían los nombres de las columnas para que no distingan entre mayúsculas y minúsculas. El propio SQL no se preocupa por el caso, ¿por qué debería el Cursor? – nobre

+0

información sobre 'por qué' aquí: https://code.google.com/p/android/issues/detail?id=42636 –

1

El enfoque mejor y recomendado el uso de SQLite es que se declara todo su nombre de la tabla y el nombre de la columna static, final y class nivel .. por ejemplo:

// write table name 
public static final String TABLE_MESSAGE = "messages"; 
// and column name accordingly 
public static final String COLUMN_ID = "_id"; 
public static final String COLUMN_MESSAGE = "message"; 

por lo que la ventaja de este enfoque es que don' Necesito recordar la ortografía y el caso, etc. de los nombres de las tablas y columnas.

cuando acceda a cualquier tabla o columna que sólo tiene que utilizar estas variables estáticas, por ejemplo:

// TABLE creation sql statement 
private static final String TABLE_CREATE = "create table " 
      + TABLE_MESSAGE + "(" + COLUMN_ID 
      + " integer primary key autoincrement, " + COLUMN_MESSAGE 
      + " text not null);"; 

al consultar:

database.query(TABLE_MESSAGE, new String[]{COLUMN_ID,COLUMN_MESSAGE}, null, null, null, null, null); 

o puede ser utilizado en Cursor

int index = cursor.getColumnIndex(COLUMN_MESSAGE); 

esto le ayudará a evitar tales conflictos de sensibilidad de mayúsculas y minúsculas y errores ortográficos. :)

+0

Muchas gracias. Pero en realidad no estoy creando mi base de datos usando código. Necesito usar una base de datos existente. ¿Por qué lo necesito? porque tiene algunos datos predeterminados. Probé diferentes enfoques para "cómo proporcionar a la base de datos algunos datos predeterminados" y me pareció la mejor manera de tener una base de datos ya creada y poblada con datos predeterminados. –

+0

, entonces necesita explorar la base de datos y ver el nombre de la tabla y columna una vez y luego usar sus variables :) –

1

Otra forma sería la de consultar la base de sí mismo para el nombre correcto mediante el uso de PRAGMA table_info, así que escribí un método para eso:

public class database { 
    private SQLiteDatabase mainDB = null; 

    private boolean CreateOrOpenDB() { 
     try { 
      if (mainDB == null || !mainDB.isOpen()) { 
       mainDB = Context.openOrCreateDatabase("mainDB", SQLiteDatabase.CREATE_IF_NECESSARY, null); 
      } 
     } catch (SQLiteException e) { 
      return false; 
     } 
     return true; 
    } 

    private String GetTrueColumnName(String TableName, String column) { 
     String TrueColName = ""; 
     if (CreateOrOpenDB()) { 
      try { 
       Cursor c = mainDB.rawQuery("PRAGMA table_info(" + TableName + ");", null); 

       if (c != null) { 
        if (c.moveToFirst()) { 
         do { 
          String dbcolumn = c.getString(c.getColumnIndex("name")); 
          if (column.toLowerCase().equals(dbcolumn.toLowerCase())) { 
           TrueColName = dbcolumn; 
           break; 
          } 
         } while (c.moveToNext()); 
        } 
        c.close(); 
       } 
       mainDB.close(); 
      } catch (Exception e) { 
      } 
     } 
     return TrueColName; 
    } 
} 

entonces todo lo que tiene que llamar es:

String CorrectName = GetTrueColumnName(TableName, "RuLeS");

y sí, sé que va a ser duro en la base de datos. Pero funciona y es estable

Cuestiones relacionadas