2012-04-10 51 views
7

我想查詢表中的所有列到一個長文本視圖和/或字符串。我知道這可能不是正確的做事方式,但我必須這樣做。糾正我,如果我錯了,我是移動未來將獲得該行的下一列的印象:android cursor.moveToNext()?

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

我認爲這會得到第一列和顯示的所有內容,而不是我得到的第一列和第一行。我究竟做錯了什麼?有沒有更好的或真正的方法來獲取這些信息而不使用ListView?

回答

9

爲了清楚起見,下面我將介紹一個完整的例子,我相信這些例子是令人感興趣的。如代碼註釋所示,我們基本上遍歷數據庫行,然後遍歷列以根據數據庫形成數據表。

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將光標移動到下一行。而c.getString(0)總是會給你第一列,如果有的話。我認爲你應該做一些類似的你的循環

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

cursor.moveToFirst()將光標移動到第一行內。如果您知道您有6列,並且您想要一個包含所有列的字符串,請嘗試以下操作。

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

如果您不知道列數,只需在'for'循環中使用'c.getColumnCount()'。 – Squonk 2012-04-10 01:52:41

0

我編碼我遍歷這樣的cusror:

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

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

     cursor.moveToNext(); 
    } 

永遠奏效。這將檢索所有行的列「column_name」的值。 你的錯誤是你遍歷行而不是列。 要遍歷所有的列:

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

這將循環在第一行的列和檢索每個列的值。

30

簡單的使用方法是:

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

moveToFirst當你需要開始從開始迭代您已經達到一定位置後使用。

避免使用cursor.getCount(),除非需要。 永遠不要使用循環getCount()。

getCount代價很高 - 它遍歷許多記錄來計算它們。它不返回一個存儲的變量。第二個電話可能會有一些緩存,但第一個電話在計數之前不知道答案。

如果您的查詢匹配1000行,則光標實際上只有第一行。每個moveToNext都會搜索並找到下一個匹配項。 getCount必須找到全部1000個。如果只需要10個,爲什麼要遍歷所有1000個?爲什麼迭代兩次?另外,如果您的查詢不使用索引,getCount可能會更慢 - 即使查詢僅匹配100,getCount可能會超過10000條記錄。爲什麼循環20000而不是10000?

+1

從Android 4.2開始,'moveToNext()'由'moveToPosition()'實現,它本身也調用'.getCount()'](http:// androidxref。COM/4.2.2_r1 /外部參照/框架/鹼/核心/ JAVA /機器人/數據庫/ AbstractCursor.java#moveToPosition)。當然,這只是實施細節,不應該依賴。 – kennytm 2013-08-14 08:33:38

+1

@KennyTM是對的。事實上,在Android 4.2之前,情況就是如此(請參閱http://bit.ly/1s8KClM)。此外,除了moveToNext()幾乎所有其他基本的遊標操作(例如'moveToFirst()','isBeforeFirst()'和'isFirst()')都涉及調用getCount()。所以即使'getCount()'很貴,也是不可避免的。此外,'getCount()'的實現會緩存返回的值,因此至少後續的調用將會很便宜(請參閱http://bit.ly/1uL4ZEp)。 – Matthias 2014-09-18 16:05:22