sql >> Base de Datos >  >> RDS >> SQLite

Insertar o actualizar Android SQLite

Creo que está preguntando cómo INSERTAR nuevas filas o ACTUALIZAR sus filas existentes en un solo paso Si bien eso es posible en un solo SQL sin procesar como se describe en esta respuesta, descubrí que es más fácil hacerlo en dos pasos en Android usando SQLiteDatabase.insertWithOnConflict() usando CONFLICT_IGNORE para 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
}

Este ejemplo supone que la clave de la tabla está configurada para la columna "_id", que conoce el registro _id y que ya existe la fila n.º 1 (_id=1, columnaA ="valorA", columnaB ="valorB"). Aquí está la diferencia usando insertWithOnConflict con CONFLICT_REPLACE y CONFLICT_IGNORE

  • CONFLICT_REPLACE sobrescribirá los valores existentes en otras columnas a nulos (es decir, la columna B se convertirá en NULL y el resultado será _id=1, columnA ="valueNEW", columnB =NULL). Pierdes los datos existentes como resultado y no los uso en mi código.
  • CONFLICT_IGNORE omitirá el INSERTO SQL para su fila #1 existente y ACTUALIZARÁ SQL esta fila en el siguiente paso conservando el contenido de todas las demás columnas (es decir, el resultado será _id=1, columnaA ="valorNUEVO", columnaB ="valorB").

Cuando intente insertar la nueva fila #2 que aún no existe, el código solo ejecutará SQL INSERT en la primera instrucción insertWithOnConflict (es decir, el resultado será _id=2, columnA ="valueNEW", columnB =NULL).

Tenga cuidado con este error que está causando que SQLiteDatabase.CONFLICT_IGNORE funcione mal en API10 (y probablemente en API11). La consulta devuelve 0 en lugar de -1 cuando pruebo en Android 2.2.

Si no conoce la clave de registro _id o tiene una condición que no creará un conflicto, puede invertir la lógica para ACTUALIZAR o INSERTAR . Esto mantendrá su clave de registro _id durante ACTUALIZAR o creará un nuevo registro _id durante INSERTAR.

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

El ejemplo anterior asume que solo desea ACTUALIZAR el valor de la marca de tiempo en el registro, por ejemplo. Si llama primero a insertWithOnConflict, INSERT creará un nuevo registro _id debido a la diferencia en la condición de marca de tiempo.