Android: SQLite – insertWithOnConflict
Estoy llamando a insertWithOnConflict, usando SQLiteDatabase.CONFLICT_IGNORE. Sin embargo, cuando se produce un conflicto "-1" se devuelve en lugar del id de la fila existente. ¿Cómo puedo corregir esto?
Creación de tablas:
- Base de datos de SQLite de SQL, bloqueo y versión
- El comodín no funciona en SQLite
- Obteniendo un valor único de SQLite en android
- Cambiar la profundidad de bits de Bitmap
- Cursor finalizado sin cerrar antes () en ListFragment
EDIT:
String CREATE_CATEGORY_TABLE = "CREATE TABLE "+TABLE_CATEGORY+"(" + BaseColumns._ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+ KEY_CATEGORY_NAME+" TEXT UNIQUE" + ")"; db.execSQL(CREATE_CATEGORY_TABLE);
Insertar declaración:
ContentValues values = new ContentValues(); values.put(KEY_CATEGORY_NAME, name); int catID = (int) db.insertWithOnConflict(TABLE_CATEGORY, null, values, SQLiteDatabase.CONFLICT_IGNORE);
- La base de datos Android está dañada, pero puede abrirse en SQLite Manager. ¿Recuperable?
- Problema en sqlite con "como" en android
- Base de datos SQLite de Android, ¿POR QUÉ caída de tabla y volver a crear en la actualización
- ormlite para android: ayuda de diseño y más
- Android - ¿Existe la base de datos SQLite?
- Android: Actualización de bases de datos locales desde una base de datos en línea
- Android Seleccionar fila por Id en Sqlite?
- Intenta invocar el método virtual 'java.lang.Class java.lang.reflect.Field.getType ()' en una referencia de objeto nulo
InsertWithOnConflict, utilizando SQLiteDatabase.CONFLICT_IGNORE no funciona como se esperaba y probablemente debería evitarse por completo, como en este problema:
https://code.google.com/p/android/issues/detail?id=13045
Android espera que la columna de clave principal se llame _id
. Puede ser la causa: puesto que la columna no existe, no puede devolver el valor y devuelve -1.
SQLiteDatabase.CONFLICT_IGNORE comentario se supone que funciona de la misma manera que usted había observado. Al intentar insertar, si no hay ninguna fila en conflicto, se insertará una nueva fila con los valores dados y devolverá el id de la fila recién insertada. Por otro lado, si ya hay una fila en conflicto (con la misma clave única), los valores entrantes se ignorarán y la fila existente se conservará y el valor devuelto será -1 para indicar un escenario de conflicto. Para conocer más detalles y entender cómo manejar este valor de retorno, lea Android / SQLite: Insertar-Actualizar columnas de tabla para mantener el identificador
La solución que usé es usar insertOrThrow
lugar de insertWithOnConflict
y capturar explícitamente SQLiteConstraintException
. Necesita capturarlo explícitamente porque hereda de RuntimeException
.
Tuve que utilizar esta solución, ya que insert
fue el dumping del esquema de base de datos a los registros cuando había un conflicto, y que era inaceptable.
try { long id = db.insertWithOnConflict(StatusData.TABLE, null, values, SQLiteDatabase.CONFLICT_IGNORE); if (id == -1){ throw new RuntimeException(String.format("%s: Failed to insert [%s] to [%s] for unkwon reason.",TAG,values,uri)); }else return ContentUris.withAppendedId(uri, id); }
Todavía puedo obtener la fila insertada en la base de datos, el CONFLICT_IGNORE no funciona como se esperaba @Tom es correcto, pero no estoy seguro de si ese problema fue corregido
- No se puede analizar como entero
- Mi aplicación no aparecerá en el diálogo del selector para android.intent.action.VIEW con mime tipo video / * only en Marshmallow