Android SQLite 挿入または更新 質問する

Android SQLite 挿入または更新 質問する

ドキュメントに記載されているように、挿入または更新を行う構文は次のとおりです。INSERT OR REPLACE INTO <table> (<columns>) VALUES (<values>)質問は、以下をマージする関数があるかどうかです。

public long insert (String table, String nullColumnHack, ContentValues values) 
public int update (String table, ContentValues values, String whereClause, String[] whereArgs)

それとも準備された SQL ステートメントと rawQuery を使用して実行する必要がありますか?

Android で挿入または更新を行うためのベスト プラクティスは何ですか?

ベストアンサー1

どのようにすればよいかお尋ねだと思います新しい行を挿入するか、既存の行を更新します1ステップで実行できます。これは、前述のように単一の生SQLで実行できますが、この答えAndroidでは、2つのステップでこれを行う方が簡単だとわかりました。SQLiteDatabase.insertWithOnConflict()conflictAlgorithm に CONFLICT_IGNORE を使用します。

ContentValues initialValues = new ContentValues();
initialValues.put("_id", 1); // the execution is different if _id is 2
initialValues.put("columnA", "valueNEW");

int id = (int) yourdb.insertWithOnConflict("your_table", null, initialValues, SQLiteDatabase.CONFLICT_IGNORE);
if (id == -1) {
    yourdb.update("your_table", initialValues, "_id=?", new String[] {"1"});  // number 1 is the _id here, update to variable for your code
}

この例では、テーブル キーが列 "_id" に設定され、レコード _id がわかっており、行 #1 (_id=1、columnA = "valueA"、columnB = "valueB") がすでに存在することを前提としています。CONFLICT_REPLACE と CONFLICT_IGNORE で insertWithOnConflict を使用した場合の違いは次のとおりです。

  • CONFLICT_REPLACE は、他の列の既存の値を NULL に上書きします (つまり、columnB は NULL になり、結果は _id=1、columnA = "valueNEW"、columnB = NULL になります)。結果として既存のデータが失われるため、コードでは使用しません。
  • CONFLICT_IGNORE は、既存の行 #1 の SQL INSERT をスキップし、次のステップで他のすべての列の内容を保持しながらこの行を SQL UPDATE します (つまり、結果は _id=1、columnA = "valueNEW"、columnB = "valueB" になります)。

まだ存在しない新しい行 #2 を挿入しようとすると、コードは最初のステートメント insertWithOnConflict でのみ SQL INSERT を実行します (つまり、結果は _id=2、columnA = "valueNEW"、columnB = NULL になります)。

気づくこのバグこれにより、SQLiteDatabase.CONFLICT_IGNORE が API10 (おそらく API11) で誤動作を起こします。Android 2.2 でテストすると、クエリは -1 ではなく 0 を返します。

レコードキー_idがわからない場合、または競合が発生しない条件がある場合は、ロジックをUPDATEまたはINSERTに反転するこれにより、UPDATE 中にレコード キー _id が保持され、INSERT 中に新しいレコード _id が作成されます。

int u = yourdb.update("yourtable", values, "anotherID=?", new String[]{"x"});
if (u == 0) {
    yourdb.insertWithOnConflict("yourtable", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}

上記の例では、たとえばレコード内のタイムスタンプ値を更新するだけであると想定しています。最初に insertWithOnConflict を呼び出すと、タイムスタンプ条件の違いにより、INSERT によって新しいレコード _id が作成されます。

おすすめ記事