2013年1月22日火曜日

Cursor.moveToFirst は別に必須ではない

Android の SQLiteDatabase なんかを使用してデータベースに問い合わせを行い、その結果を Cursor で受け取る、という処理は毎日の習慣のような感じでいつも使うわけですが、何故かこれに対して、次のような Cursor.moveToFirst してから Cursor.moveToNext するコードがよく見られます。

Cursor cursor = db.query(...);
if (cursor.moveToFirst()) {
    do {
        cursor.getString(...);
        ...
    } while (cursor.moveToNext());
}

多分最初のカーソル位置がどこにあるか良く分からないとか、名前的にまあ First に移動してから Next に移動するのが正しいんだろう、という感覚で書いてると思うんですが、実際は Cursor.getPosition のドキュメントに次のような記載があります。

When the row set is first returned the cursor will be at positon -1, which is before the first row. 
行セットが最初に返されたとき、カーソルの位置は -1, つまり最初の行の一つ前に設定されています。
つまり、 Cursor インスタンスを受け取ってから最初の Cursor.moveToNext 呼び出しで先頭行を取り出せることはちゃんと仕様上保証されているので、次のように単純なループで書いて大丈夫です。

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

何となくコピペプログラミングで感染しまくってる感があったので、ただそれだけですがメモ。

4 件のコメント:

  1. 複数のデータを取得した場合Cursor.moveToFirstから始めてmoveToNext で次に移動するという手順を踏まないと最初の一つが欠落するという現象があるのでネット上のサンプルでCursor.moveToFirstが使われているのはそれの対策だと思います。
    例外などのエラーは起きないので動作上は必須ではないですが先頭のデータが回収できません。

    仕様書が間違っているか、バグのどちらかだと思いますが、プログラムのコードの読み方的に仕様書が間違っているようにおもえます。

    返信削除
  2. と思ったけどすいません、違いました。 こちらの手違いでちゃんとmoveToNextで最初から出来ますね。

    返信削除
  3. Best Merkur Razors - Review - Seles Casino
    Merkur Razors, Razors and 인카지노 Blades — Merkur Razors. Merkur is a well planet win 365 known brand. It is 메리트카지노 the most popular brand in the wet shaving world. The Merkur

    返信削除
  4. Wynn casino to become COVID-19 vaccine center - Dr.
    LAS VEGAS (FOX5) -- Wynn 구미 출장샵 Resorts Ltd. will be taking on 의정부 출장샵 the coronavirus 삼척 출장안마 pandemic in the wake of a new COVID-19 vaccine 전라남도 출장마사지 center 성남 출장안마 in

    返信削除