2012-04-10 3 views
7

Próbuję wykonać zapytanie do wszystkich kolumn w tabeli w jeden długi widok tekstowy i/lub ciąg. Wiem, że to nie może być właściwy sposób, ale muszę to zrobić. Popraw mnie jeśli się mylę, byłem pod wrażeniem, że poruszać się obok dostanie kolejną kolumnę w wierszu:android cursor.moveToNext()?

Cursor c = db.get(); 
if(c.moveToFirst){ 
do{ 
string = c.getString(0); 
}while(c.moveToNext); 

Myślałem, że to dostać pierwszą kolumnę i wyświetlić całą jego zawartość, a nie otrzymuję pierwsza kolumna i pierwszy wiersz. Co ja robię źle? Czy istnieje lepszy lub rzeczywisty sposób uzyskania tych informacji bez użycia ListView?

Odpowiedz

9

Dla jasności kompletny przykład byłby następujący, który, jak ufam, jest interesujący. Jak wskazano w komentarzach do kodu, zasadniczo iterujemy po wierszach bazy danych, a następnie kolumnach, aby utworzyć tabelę danych zgodnie z bazą danych.

Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, 
      null); 

    //if the cursor isnt null we will essentially iterate over rows and then columns 
    //to form a table of data as per database. 
    if (cursor != null) { 

     //more to the first row 
     cursor.moveToFirst(); 

     //iterate over rows 
     for (int i = 0; i < cursor.getCount(); i++) { 

      //iterate over the columns 
      for(int j = 0; j < cursor.getColumnNames().length; j++){ 

       //append the column value to the string builder and delimit by a pipe symbol 
       stringBuilder.append(cursor.getString(j) + "|"); 
      } 
      //add a new line carriage return 
      stringBuilder.append("\n"); 

      //move to the next row 
      cursor.moveToNext(); 
     } 
     //close the cursor 
     cursor.close(); 
    } 
1

moveToNext przenosi kursor do następnego rzędu. i c.getString (0) zawsze da ci pierwszą kolumnę, jeśli taka istnieje. Myślę, że należy zrobić coś podobnego do tego wewnątrz pętli

int index = c.getColumnIndex("Column_Name"); 
string = c.getString(index); 
1

cursor.moveToFirst() przesuwa kursor do pierwszego rzędu. Jeśli wiesz, że masz 6 kolumn i chcesz mieć jeden ciąg zawierający wszystkie kolumny, spróbuj wykonać następujące czynności.

c.moveToFirst(); 
StringBuilder stringBuilder = new StringBuilder(); 
for(int i = 0; i < 6; i++){ 
    stringBuilder.append(c.getString(i)); 
} 

// to return the string, you would do stringBuilder.toString(); 
+1

A jeśli nie znasz liczby kolumn, po prostu użyj 'c.getColumnCount()' w pętli 'for'. – Squonk

0

jestem kodowania moje pętle nad cusror tak:

cursor.moveToFirst(); 
    while(!cursor.isAfterLast()) { 

      cursor.getString(cursor.getColumnIndex("column_name")); 

     cursor.moveToNext(); 
    } 

To zawsze działa. Spowoduje to pobranie wartości kolumny "column_name" wszystkich wierszy. Twoim błędem jest pętla nad wierszami, a nie kolumnami. Do pętli na kolumnach:

cursor.moveToFirst();  
    for(int i = 0; i < cursor.getColumnNames().length; i++){ 
     cursor.getString(i); 
    } 

To będzie pętla na łamach pierwszego rzędu i odzyskać każdą wartość kolumny.

30

Proste użycie jest:

Cursor cursor = db.query(...); 
while (cursor.moveToNext()) { 
    ... 
} 

moveToFirst jest używany, gdy trzeba zacząć od początku iteracji po osiągnęły już pewną pozycję.

Unikaj używania cursor.getCount(), chyba że jest to wymagane. I nigdy nie używaj pętli przez getCount().

getCount jest drogi - iteruje po wielu rekordach, aby je policzyć. Nie zwraca zmiennej przechowywanej. Podczas drugiego połączenia może występować buforowanie, ale pierwsze wywołanie nie zna odpowiedzi, dopóki nie zostanie zliczone.

Jeśli zapytanie pasuje do 1000 wierszy, kursor ma tylko pierwszy wiersz. Każdy moveToNext wyszukuje i znajduje następny mecz. getCount musi znaleźć wszystkie 1000. Dlaczego iterować wszystko, jeśli potrzebujesz tylko 10? Dlaczego iterować dwa razy?

Ponadto, jeśli zapytanie nie używa indeksu, getCount może być jeszcze wolniejsze - getCount może przekroczyć 10000 rekordów, nawet jeśli zapytanie pasuje tylko do 100. Dlaczego pętla 20000 zamiast 10000?

+1

Od wersji Androida "moveToNext()" jest implementowane przez 'moveToPosition()', które [samo również wywołuje '.getCount()'] (http: // androidxref.com/4.2.2_r1/xref/frameworks/base/core/java/android/database/AbstractCursor.java # moveToPosition). Z pewnością jest to po prostu szczegół wdrażania, na który nie należy polegać. – kennytm

+1

@KennyTM ma rację. W rzeczywistości było tak nawet przed Androidem 4.2 (patrz http://bit.ly/1s8KClM). Ponadto, oprócz 'moveToNext()' prawie wszystkie inne podstawowe operacje kursora (np. 'MoveToFirst()', 'isBeforeFirst()' i 'isFirst()') obejmują wywoływanie (wywołania) do 'getCount()'. Więc nawet jeśli 'getCount()' jest kosztowne, jest nieuniknione. Co więcej, implementacja 'getCount()' buforuje zwróconą wartość, więc co najmniej kolejne wywołania będą tanie (zobacz http://bit.ly/1uL4ZEp). – Matthias

Powiązane problemy