2011-01-30 12 views
7

Mam bardzo podstawowe sytuacji:Android SQLite ORDER BY nie działa

Mam tabeli z około 5k rzędów:

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

Który ja okresowo aktualizować za pomocą „Update słowa SET rand = random()”

w Android, gdy tworzę kursora używając rawQuery(), przy użyciu następujących:

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

Zwrócony kursor nie jest iterowany we właściwej kolejności. Na przykład. wyświetli kolumny z wartościami rand w następującej kolejności:

-1298882092 
-2138143484 
-1115732861 
118839193 
... 

Czy ktoś wie, co się tutaj dzieje? Czy to nie powinno działać? Jeśli uruchomię dokładnie to samo zapytanie w SQLiteManager, zwróci ono wyniki we właściwej kolejności, więc wydaje się, że jest to specyficzne dla androida/kursora.

UPDATE:

Oto kod w android, próbowałem wiele sposobów:

Attempt 1:

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

Próba 2:

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

W obu przypadkach I iteracyjne jak poniżej:

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

Nie na Androida, ale wydaje się działać tutaj: http://ideone.com/GEnG3 –

+1

Tak, to działa również w sqlitemanager, więc myślę, że jest to specyficzne dla Androida. Rzeczywisty przypadek ma również 5k wierszy i indeks na kolumnie rand. – ghempton

+0

Czy możesz opublikować kod Androida? –

Odpowiedz

6

Rozwiązałem to, było proste niedopatrzenie. Funkcja random() zwraca wartość, która może być większa niż typ danych java int. To powodowało przepełnienie. Przełączony na getLong() i wszystko działa poprawnie. Kursor poprawnie sprawdzał się przez cały czas.

+1

Dobra robota, zastanawiasz się.Ciche usterki związane z obciętymi intami mogą być naprawdę trudne do debugowania –

1

Miałem problem z kursorem android, rawquery i grupowanie według. Wynik nie został zamówiony.

Jest to tabela:

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

I to było zapytanie kopalni:

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 ? "; 

i tu, jak go używać:

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

gdzie jestem pewien że QID jest liczba całkowita i kolejność i.titolo ASC lub DESC

Jedyne obejście że pracował dla mnie jest zmodyfikować kwerendę poruszający grupę przez clausole w sposobie połączenia 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)});