I am calling insertWithOnConflict, using SQLiteDatabase.CONFLICT_IGNORE. However, when a conflict occurs “-1” is returned instead of the id of the existing row. How do I correct this?
Table creation:
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);
Insert statement:
ContentValues values = new ContentValues();
values.put(KEY_CATEGORY_NAME, name);
int catID = (int) db.insertWithOnConflict(TABLE_CATEGORY, null, values, SQLiteDatabase.CONFLICT_IGNORE);
insertWithOnConflict, using SQLiteDatabase.CONFLICT_IGNORE does not work as expected and should probably be avoided altogether, as per this issue:
https://code.google.com/p/android/issues/detail?id=13045
Answer:
SQLiteDatabase.CONFLICT_IGNORE comment is supposed to function the same way as you had observed. While trying to insert, if there is no conflicting row, then it will insert a new row with the given values and return the id of the newly inserted row. On the other hand if there is already a conflicting row (with same unique key), then the incoming values will be ignored and the existing row will be retained and then the return value will be -1 to indicate a conflict scenario. To know further details and to understand how to handle this return value, please read Android/SQLite: Insert-Update table columns to keep the identifier
Answer:
Android expects the primary key column to be called _id
. Might be the cause: since the column does not exist, it can’t return the value and returns -1.
Answer:
The workaround that I used is using insertOrThrow
instead of insertWithOnConflict
, and explicitly catching SQLiteConstraintException
. You need to explicitly catch it because it inherits from RuntimeException
.
I had to use this workaround because insert
was dumping the database scheme to the logs when there was a conflict, and that was unacceptable.
Answer:
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);
}
I am still able to get the row inserted into the database, the CONFLICT_IGNORE does not work as expected @Tom is right but i am not sure if that issue was fixed
Tags: androidandroid, sql, sqlite