2011-01-30 12 views
7

tengo una situación muy básico:Android SQLite ORDER BY no funciona

Tengo una tabla con filas alrededor de 5k:

CREATE TABLE "words" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "name" TEXT NOT NULL , "def" TEXT NOT NULL, "rand" INTEGER) 

Qué puedo actualizar periódicamente el uso de "palabras ACTUALIZACIÓN rand SET = aleatoria()"

En androide, cuando creo un cursor utilizando rawQuery() utilizando la siguiente:

SELECT w.id, w.name, w.def, w.rand FROM words w ORDER BY w.rand ASC; 

El cursor devuelto no itera en el orden correcto. P.ej. generará columnas con valores rand en el siguiente orden:

-1298882092 
-2138143484 
-1115732861 
118839193 
... 

¿Alguien sabe qué está pasando aquí? ¿No debería funcionar esto? Si me quedo la misma consulta exacta en SQLiteManager devuelve los resultados en el orden correcto, por lo que este parece ser el androide/cursor específico.

ACTUALIZACIÓN:

Aquí está el código de Android, he intentado varias maneras:

Intento 1:

Cursor cursor = db.rawQuery("SELECT w.id, w.name, w.def, w.rand FROM words w ORDER BY w.rand ASC", new String[]{}); 

Intento 2:

Cursor cursor = db.query("words", new String[]{"id", "name", "def", "rand"}, 
      null, null, null, null, "rand ASC"); 

En ambos casos itero como la siguiente:

while(cursor.moveToNext()) { 
    ... 
    Log.i("Test", cursor.getInt(3)); 
    ... 
} 
+0

No en Android, pero parece que funciona aquí: http://ideone.com/GEnG3 –

+1

Sí, funciona en sqlitemanager también, así que creo que es específico de Android. El caso real también tiene 5k filas y un índice en la columna rand. – ghempton

+0

¿Puedes publicar el código de Android? –

Respuesta

6

Lo resuelto, fue un simple descuido. La función random() devuelve un valor que puede ser mayor que un tipo de datos java int. Esto estaba produciendo desbordamiento. Cambió a getLong() y todo funciona bien. El cursor se repetía correctamente todo el tiempo.

+1

Buen trabajo descifrarlo.Los errores de truncado int pueden ser muy difíciles de depurar –

1

que tenía un problema con el cursor androide, rawquery y agrupar. El resultado no fue ordenado.

Esta es la tabla:

public static final String I_ID = "iid"; 
public static final String I_QID = "qid"; 
public static final String I_STATUS = "status"; 
public static final String I_PDATE = "pub_date"; 
public static final String I_TYPE = "tipo"; 
public static final String I_TITLE = "titolo"; 
public static final String I_LINK = "link"; 
public static final String I_QR = "qrcode"; 
public static final String I_DESC = "descrizione"; 

private static final String C_ITEM_T = 
     "CREATE TABLE \""+T_ITEM+"\" ("+ 
     "\""+I_ID+"\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"+ 
     "\""+I_QID+"\" INTEGER NOT NULL REFERENCES "+T_QUERY+"("+Q_ID+") ,"+ 
     "\""+I_STATUS+"\" INTEGER NOT NULL,"+ 
     "\""+I_PDATE+"\" TEXT NOT NULL,"+ 
     "\""+I_TYPE+"\" TEXT NOT NULL,"+ 
     "\""+I_TITLE+"\" TEXT NOT NULL,"+ 
     "\""+I_LINK+"\" TEXT UNIQUE NOT NULL,"+ 
     "\""+I_QR+"\" TEXT UNIQUE NOT NULL,"+ 
     "\""+I_DESC+"\" TEXT"+ 
     ");"; 

public static final String A_ID = "aid"; 
public static final String A_IID = "iid"; 
public static final String A_SIZE = "grandezza"; 
public static final String A_DURATION = "durata"; 
public static final String A_CHANNELS = "canali"; 
public static final String A_RATE = "sampleRate"; 
public static final String A_TORRENT = "torrent"; 
public static final String A_DOWNLOAD = "download"; 
public static final String A_LICENSE_URL = "licenza_url"; 
public static final String A_TAGS = "tags"; 
public static final String A_CREATOR = "creatore"; 

private static final String C_ATTR_T = 
     "CREATE TABLE \""+T_ATTR+"\" ("+ 
     "\""+A_ID+"\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"+ 
     "\""+A_IID+"\" INTEGER NOT NULL REFERENCES "+T_ITEM+"("+I_ID+") ,"+ 
     "\""+A_SIZE+"\" LONG NOT NULL,"+ 
     "\""+A_DURATION+"\" LONG NOT NULL,"+ 
     "\""+A_CHANNELS+"\" TEXT NOT NULL,"+ 
     "\""+A_RATE+"\" TEXT NOT NULL,"+ 
     "\""+A_TORRENT+"\" TEXT NOT NULL,"+ 
     "\""+A_DOWNLOAD+"\" TEXT NOT NULL,"+ 
     "\""+A_LICENSE_URL+"\"TEXT,"+ 
     "\""+A_TAGS+"\" TEXT,"+ 
     "\""+A_CREATOR+"\" TEXT,"+ 
     "UNIQUE ("+A_ID+","+A_IID+")"+ 
     ");"; 

y esta fue la consulta de minas:

public static final String FILL_GRID = "SELECT * "+ 
     "FROM "+ Db.T_ITEM + " i " + 
     "LEFT OUTER JOIN "+Db.T_ATTR+" a ON (i."+Db.I_ID+"=a."+Db.A_IID+ ")"+ 
     " WHERE i."+Db.I_QID+" = ? AND i."+Db.I_STATUS+" <> "+Db.STATUS_DELETED + 
        " GROUP BY ? "; 

y aquí cómo lo uso:

Cursor c = db.rawQuery(FILL_GRID, new String[]{String.valueOf(qid), order}); 

donde estoy seguro de que qid es un número entero, y el orden i.titolo ASC o DESC

La única solución que trabajó para mí es modificar la consulta mover el grupo de clausole en el método llamado rawquery:

public static final String FILL_GRID = "SELECT * "+ 
     "FROM "+ Db.T_ITEM + " i " + 
     "LEFT OUTER JOIN "+Db.T_ATTR+" a ON (i."+Db.I_ID+"=a."+Db.A_IID+ ")"+ 
     " WHERE i."+Db.I_QID+" = ? AND i."+Db.I_STATUS+" <> "+Db.STATUS_DELETED; 

Cursor c = db.rawQuery(FILL_GRID + " ORDER BY " + order, new String[]{String.valueOf(qid)});