1


0

ORDER ID desc limitを使用してsqlite / Androidの最後の行の単一の列を取得する1

データベースの最後の行から値を取得し、それをEditTextフィールドに挿入できるメソッドを作成しようとしています。 (これは、ユーザーがそれほど頻繁に変更することはないため、設定したときに、戻ったときに設定が維持されると便利です)。

特定の列の合計を取得するための同様の方法に基づく私の方法は、次のとおりです。

public String getBase() {
 Cursor mCursor = mDb.rawQuery(
   "SELECT base FROM table constants ORDER ID desc limit 1", null);
 if (mCursor.moveToFirst()) {
  return mCursor.getString(0);
 }
 return mCursor.getString(0);

私が言ったように、私はこれをインターネットを検索した後に見つけた同様の方法に基づいています。 私はその大部分を理解していますが、returnステートメントの0(またはmoveToFirstメソッド)の意味がわかりません。

とにかく、OnClickListener(ユーザーがこの値をdbに保存するために押すボタン)には、次のものがあります(editBaseは、設定するEditTextフィールドです):

editBase.setText(cDbHelper.getBase());

このステートメントなしでプログラムを実行すると、正常に機能し、値がデータベースに保存されます。 これで実行しようとするとすぐに、私は力を近づけます。 助言がありますか?

ありがとう。

編集:回答いただきありがとうございます。 友人からのいくつかのガイダンスで、私は「ORDER BY …​ 代わりにdesc limit 1 "。 これが最終的な方法です。

public double getBase() {
    final double DEFAULT_BASE = 0;
    Cursor mCursor = mDb.rawQuery(
            "SELECT base FROM constants ORDER BY _id desc limit 1", null);
    if (mCursor.getCount() == 0)
        return DEFAULT_BASE;
    else
        mCursor.moveToFirst();
        return mCursor.getDouble(0);

2 Answer


0


1)DBのクエリについては、次を試してください。

SQLiteDatabaseには、 `query(String table、String [] columns、String selection、String [] selectionArgs、String groupBy、String having、String orderBy、String limit)`メソッドがあります。

少なくともこれでは、SQLを手動で構築する必要はありません。

2)カーソルのドキュメントを確認します:http://developer.android.com/reference/android/database/Cursor.html#getString(int)

0はcolumnIndexです。


0


おそらく、別のスレッドでジョブを実行しているときにビューを更新しようとしています。これはほとんど常に強制終了をトリガーします。

この記事http://developer.android.com/resources/articles/painless-threading.html[Painless Threading]では、長時間実行されている作業を別のスレッドに分割する方法(および「戻る」方法)を学習します。それに)。 基本的には、GUIスレッド(またはイベントキューまたはUIスレッド)に、コントロールとビューにアクセスして実行するには「Runnable」が必要であることを伝えることができます。

private void clicked() {
    // called from a click of a button for instance
    new Thread(new Runnable() {
        public void run() {
            // the long running job should be executed on a different
            // thread as to not stall the ui thread
            runLongWork();
        }
    }
}

private void runLongWork() {
    // this is method running on separate thread
    // so we should run a runnable on the ui thread instead to update our view's.
    this.runOnUiThread(new Runnable() {
        public void run() {
            // Now we are back in the ui thread
            editBase.setText(cDbHelper.getBase());
        }
    }
}

他の質問についてはhttps://stackoverflow.com/questions/4144546/retrieving-a-single-column-of-last-row-in-sqlite-android-using-order-id-desc-limi/4148811#4148811 [Arhimed]はすでに部分的に答えました。 Sqliteデータベースに対してクエリを実行すると、クラスのインスタンスが取得されます。http://developer.android.com/reference/android/database/Cursor.html [Cursor]は、結果のリストまたは行のリストです。クエリが取得されました。 `moveToFirst`メソッドを使用して、結果の最初の行にカーソルを置きます。 次に、 `getXYZ()`メソッド(getString()など)を使用してクエリの列から値を取得し、必要な列のインデックスを渡すことができます。 この場合の0は、SQLクエリの最初の列である `base`を指します。

複数の行があり、 `moveToNext`メソッドを使用して次の行を取得できます。実際に次の行を「検出」したことを示すブール値を返すため、whileループですべての行を取得できます。行。

while (cursor.moveToNext()) {
    // next row of data, use getString, getInt or others
}

結果を 1`に制限するため、クエリは常に1つの値のみを返します。したがって、 moveToNext`を使用する必要はありません。 「moveToFirst」は、「moveToNext」と同様に、行が見つかった場合は「true」を返し、使用可能な行がもうない場合は「false」を返します。

あなたの声明は次のとおりです。クエリを実行し、最初の行に移動し、成功した場合はクエリの最初の列から文字列を返します(インデックスは0から始まります)。 行が見つからない場合、最初の列を文字列として返しますが、おそらく失敗します。 その場合、おそらくデフォルト値を返すか、例外をスローする必要があります。