2012-07-04 11 views
7

Tengo una tabla de direcciones simple con la instrucción que sigue a crear:SqlLite Android EN CONFLICTO ignorar es ignorado en el ICS

"CREATE TABLE " + ADDRESSES_TABLE + " (" + 
       KEY_ADDRESS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
       KEY_ADDRESS_COUNTRY + " TEXT, " + 
       KEY_ADDRESS_CITY + " TEXT, " + 
       KEY_ADDRESS_STREET + " TEXT, " + 
       KEY_ADDRESS_HOUSE + " TEXT, " + 
       KEY_ADDRESS_POSTAL_CODE + " TEXT," + 
       "UNIQUE("+KEY_ADDRESS_COUNTRY+","+KEY_ADDRESS_CITY+","+KEY_ADDRESS_STREET+","+KEY_ADDRESS_HOUSE+","+KEY_ADDRESS_POSTAL_CODE +") ON CONFLICT IGNORE)" 

Al agregar registros duplicados, el inserto() devuelve -1 metod y no el ID de la fila existente.

El problema es reproducible solo en 4.0+. El método funciona como se esperaba en 2.2 y 2.3.3.

¿Alguien ha enfrentado el mismo problema?

+0

¿Estás usando 'insert' o' insertWithOnConflict'? – Barak

+0

Intenté ambos, pero creo que insertWithOnConflict no tiene sentido si especifico ON CONFLICT IGNORE en TABLE CREATE. – Zzokk

Respuesta

9

Lamentablemente, la documentación de Android es incorrecta. (Y así su código realmente no funciona como se esperaba en versiones anteriores de Android, por ejemplo, 2.2 y 2.3.)

En 2.2 y 2.3, insertWithOnConflict() devolverá el valor de la función SQLite C API sqlite3_last_insert_rowid(), cuya documentación establece claramente las inserciones fallidas (p. ej., cuando se aplica la resolución ON CONFLICT, como IGNORE) no afectan el valor de retorno. Por lo tanto, si no se realizó ninguna inserción anterior para la conexión y se intentó una inserción duplicada, insertWithOnConflict() devolverá 0. Si una inserción anterior agregó una fila a cualquier tabla, el método devolverá la identificación de la fila de insertar --- de Por supuesto, esto es groseramente incorrecto.

En 4.0, insertWithOnConflict() devolverá el valor de la misma función de la API de SQLite C, excepto devolviendo -1 en lugar de 0.

Este cambio es por eso que ahora está observando el error. Pero si comprueba el resultado detenidamente en 2.2 y 2.3, verá que los identificadores de fila devueltos cuando se ejecuta la cláusula OR IGNORE no son realmente los identificadores de fila correctos (excepto por coincidencia).

+0

si este es de hecho el comportamiento correcto, debe [enviarlo como un error] (http://source.android.com/source/report-bugs.html) ... no podría doler: D –

+1

Está ahí como el número 13045: https://code.google.com/p/android/issues/detail?id=13045 –

+1

Gracias por la aclaración. Realmente confié en este método. Así que la mejor solución es: try { insertOrThrow (/ * Todos los parametros requeridos * /) } catch (SQLException e) {// Seleccione el registro necesario y obtener la clave principal de ella } ¿No es demasiado pesado para el DB en términos de tiempo? – Zzokk

Cuestiones relacionadas