SQLite
 sql >> Base de données >  >> RDS >> SQLite

Insertion ou mise à jour d'Android SQLite

Je pense que vous demandez comment INSÉRER de nouvelles lignes ou METTRE À JOUR vos lignes existantes en une seule étape. Bien que cela soit possible dans un seul SQL brut, comme indiqué dans cette réponse, j'ai trouvé qu'il était plus facile de le faire en deux étapes dans Android en utilisant SQLiteDatabase.insertWithOnConflict() en utilisant CONFLICT_IGNORE pour conflictAlgorithm.

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
}

Cet exemple suppose que la clé de table est définie pour la colonne "_id", que vous connaissez l'enregistrement _id et qu'il existe déjà la ligne 1 (_id=1, colonneA ="valeurA", colonneB ="valeurB"). Voici la différence en utilisant insertWithOnConflict avec CONFLICT_REPLACE et CONFLICT_IGNORE

  • CONFLICT_REPLACE écrasera les valeurs existantes dans d'autres colonnes en null (c'est-à-dire que la colonne B deviendra NULL et le résultat sera _id=1, columnA ="valueNEW", columnB =NULL). En conséquence, vous perdez des données existantes et je ne les utilise pas dans mon code.
  • CONFLICT_IGNORE ignorera le SQL INSERT pour votre ligne existante #1 et vous mettrez à jour SQL cette ligne à l'étape suivante en préservant le contenu de toutes les autres colonnes (c'est-à-dire que le résultat sera _id=1, columnA ="valueNEW", colonneB ="valeurB").

Lorsque vous essayez d'insérer une nouvelle ligne #2 qui n'existe pas encore, le code n'exécutera que le SQL INSERT dans la première instruction insertWithOnConflict (c'est-à-dire que le résultat sera _id=2, columnA ="valueNEW", columnB =NULL).

Méfiez-vous de ce bogue qui provoque un dysfonctionnement de SQLiteDatabase.CONFLICT_IGNORE sur API10 (et probablement API11). La requête renvoie 0 au lieu de -1 lorsque je teste sur Android 2.2.

Si vous ne connaissez pas la clé d'enregistrement _id ou si vous avez une condition qui ne créera pas de conflit, vous pouvez inverser la logique en UPDATE ou INSERT . Cela conservera votre clé d'enregistrement _id pendant UPDATE ou créera un nouvel _id d'enregistrement pendant INSERT.

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

L'exemple ci-dessus suppose que vous souhaitez simplement mettre à jour la valeur d'horodatage dans l'enregistrement par exemple. Si vous appelez d'abord insertWithOnConflict, INSERT créera un nouvel _id d'enregistrement en raison de la différence de condition d'horodatage.