web-dev-qa-db-ja.com

android cursor.moveToNext()?

テーブルのすべての列を1つの長いテキストビューや文字列にクエリしようとしています。私はこれが物事を行う正しい方法ではないかもしれないことを知っていますが、私はこれをしなければなりません。私が間違っている場合は訂正してください。次に移動すると、行の次の列が表示されるという印象を受けました。

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

これで最初の列が取得され、そのすべての内容が表示されると思いました。代わりに、最初の列と最初の行が取得されます。私は何が間違っているのですか? ListViewを使用せずにこの情報を取得するためのより良いまたは実際の方法はありますか?

10
Christian

明確にするために、完全な例は次のようになりますが、これは興味深いと思います。コードコメントが示すように、基本的にデータベースの行と列を繰り返し処理して、データベースごとにデータのテーブルを形成します。

    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();
    }
12
user1720179

簡単な使用法は次のとおりです。

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をループするのでしょうか。

33
Pla

私は次のように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);
    }

これにより、最初の行の列がループされ、各列の値が取得されます。

2
mrd

moveToNextカーソルを次の行に移動します。 c.getString(0)は、最初の列がある場合は常にそれを提供します。私はあなたがあなたのループの中でこれに似た何かをするべきだと思います

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

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();
0
Raunak