2012-04-10 1 views
7

テーブルのすべての列を1つの長いテキストビューおよび/または文字列に照会しようとしています。私はこれが正しいことではないかもしれないが、私はこれをしなければならないことを知っている。私が間違っている場合、私は次の移動の印象の下にあった行の次の列になるだろう、私を修正:android cursor.moveToNext()?

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

私は、これが最初の列を取得し、代わりに、そのすべての内容を表示するだろうと思った私が手最初の列と最初の行。私は間違って何をしていますか?リストビューを使用せずにこの情報を取得する方が良いか本当の方法がありますか?

答えて

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つの列があり、すべての列を含む1つの文字列が必要な場合は、次のようにします。

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

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は高価です - それはそれらを数えるために多くのレコードを繰り返します。ストアド変数は返されません。 2回目のコールにはキャッシングがあるかもしれませんが、最初のコールはカウントされるまで答えが分かりません。

クエリが1000行に一致する場合、カーソルは実際には最初の行のみを持ちます。各moveToNextは、次の一致を検索して見つけます。 getCountは1000をすべて検索する必要があります。なぜ10だけ必要な場合はすべてを繰り返しますか?なぜ2回繰り返しますか?

また、クエリでインデックスが使用されていない場合でも、getCountはさらに遅くなる可能性があります。クエリが100だけ一致しても、getCountは10000を超えるレコードになります。なぜ10000ではなく20000ループですか?

+1

Android 4.2以降、 'moveToNext()'は 'moveToPosition()'によって実装されていますが、 'それは' .getCount() '(http:// androidxref。com/4.2.2_r1/xref/frameworks/base/core/java /アンドロイド/データベース/ AbstractCursor.java#moveToPosition)。確かに、これは単に実装の詳細です。これは信頼されるべきではありません。 – kennytm

+1

@KennyTMが正しいです。実際、これはAndroid 4.2よりも前のケースでした(http://bit.ly/1s8KClMを参照)。さらに、 'moveToNext()'以外の基本的なカーソル操作( 'moveToFirst()'、 'isBeforeFirst()'、 'isFirst()')は 'getCount()'への呼び出しを含みます。 getCount()が高価な場合でも避けられないものです。さらに、 'getCount()'の実装は戻り値をキャッシュするので、少なくとも後続の呼び出しは安くなります(http://bit.ly/1uL4ZEpを参照)。 – Matthias

関連する問題