java - sqlite_constraint_primarykey - Restricción ÚNICA fallida: base de datos sqlite: android
error code 1555 sqlite_constraint_primarykey (8)
Estoy tratando de insertar valores en la tabla. Pero solo hay un valor insertado. Recibo un error en log cat cuando intento insertar nuevos valores.
Log cat muestra:
abort at 13 in [INSERT INTO event(totalminutesfrom,dayofweek,title,location,totalminutesto,id) VALUES (?,?,?,?,?,?)]: UNIQUE constraint failed: event.id
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: Error inserting totalminutesfrom=694 dayofweek=null title=qxs location=Eded & Mariz totalminutesto=0 id=0
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: event.id (code 1555)
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1471)
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1341)
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: at com.example.siddhi.timetablelayout.EventTableHelper.addEvent(EventTableHelper.java:76)
01-24 11:34:39.764 7763-7763/com.example.siddhi.timetablelayout E/SQLiteDatabase: at com.example.siddhi.timetablelayout.AddEventActivity$5.onClick(AddEventActivity.java:217)
Se muestra un error en estas dos líneas al insertar fila.
db.insert(TABLE, null, values);
db.addEvent(new EventData(eventTitle,dayOfWeek,totalMinutesFrom, totalMinutesTo,location));
EventTableHelper
public class EventTableHelper extends SQLiteOpenHelper {
private static final String TABLE = "event";
private static final String KEY_ID = "id";
private static final String KEY_TITLE = "title";
private static final String KEY_LOCATION = "location";
private static final String KEY_DAY_OF_WEEK = "dayofweek";
private static final String KEY_TOTAL_MINUTES_FROM = "totalminutesfrom";
private static final String KEY_TOTAL_MINUTES_TO = "totalminutesto";
public EventTableHelper(Context context) {
super(context, Constants.DATABASE_NAME, null, Constants.DATABASE_VERSION);
//3rd argument to be passed is CursorFactory instance
}
// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
//createTable(db);
}
public void createTable(SQLiteDatabase db){
String CREATE_EVENTS_TABLE = "CREATE TABLE " + TABLE + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_TITLE + " TEXT,"
+ KEY_DAY_OF_WEEK +"TEXT" + KEY_TOTAL_MINUTES_FROM +"INTEGER"
+ KEY_TOTAL_MINUTES_TO + "INTEGER" + KEY_LOCATION + "TEXT" + ")";
db.execSQL(CREATE_EVENTS_TABLE);
}
// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
// db.execSQL("DROP TABLE IF EXISTS " + TABLE);
// createTable(db);
// Create tables again
//onCreate(db);
}
// code to add the new contact
public void addEvent(EventData event) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_ID, event.getId());
values.put(KEY_TITLE,event.getTitle()); // Contact Name
values.put(KEY_DAY_OF_WEEK,event.getDayofWeek());
values.put(KEY_TOTAL_MINUTES_FROM,event.getFromMinutes());
values.put(KEY_TOTAL_MINUTES_TO,event.getToMinutes());
values.put(KEY_LOCATION,event.getLocation());
// Inserting Row
db.insert(TABLE, null, values);
//2nd argument is String containing nullColumnHack
db.close(); // Closing database connection
}
// code to get the single contact
EventData getEvent(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE, new String[] { KEY_ID,
KEY_TITLE, KEY_DAY_OF_WEEK, KEY_TOTAL_MINUTES_FROM,KEY_TOTAL_MINUTES_TO,KEY_LOCATION }, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
EventData eventData = new EventData(Integer.parseInt(cursor.getString(0)),cursor.getString(1), cursor.getString(2),
cursor.getInt(3),cursor.getInt(4),cursor.getString(5));
return eventData;
}
// code to get all contacts in a list view
public List<EventData> getAllEvents() {
List<EventData> conList = new ArrayList<EventData>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
EventData event = new EventData();
event.setId(Integer.parseInt(cursor.getString(0)));
event.setTitle(cursor.getString(1));
event.setDayofWeek(cursor.getString(2));
event.setFromMinutes(cursor.getInt(3));
event.setToMinutes(cursor.getInt(4));
event.setLocation(cursor.getString(5));
// Adding contact to list
conList.add(event);
} while (cursor.moveToNext());
}
// return contact list
return conList;
}
}
¿Cómo resolver esto?
La tabla tiene una restricción única. Eso significa que solo puede existir una fila con un valor de ID determinado. Si está intentando cambiar algunos de los valores de una fila, use ACTUALIZAR, no INSERTAR. Si está intentando agregar esta fila, debe darle una ID única y diferente o primero debe eliminar la fila preexistente. Cuál de estos es la respuesta correcta depende de lo que esté haciendo su aplicación.
Mi error fue que intenté rellenar la columna de ID
, aunque ya estaba definida como INTEGER PRIMARY KEY AUTOINCREMENT
Originalmente puse la nueva constricción infantil del antiguo. En su lugar, asegúrate de que tu columna única actual sea la primera:
CREATE TABLE TEST (client_id TEXT unique, remote_id INT unique)
Para desarrolladores que utilicen Room Persistence Library . Puedes usar
@Insert(onConflict = OnConflictStrategy.REPLACE) // or OnConflictStrategy.IGNORE
en DAO según Insertar Documentación
Su código probablemente viola la restricción de unicidad de la clave principal en un campo KEY_ID
.
Dos posibles soluciones son:
- Asegúrese de que su
EventData.getId()
devuelva valores únicos por objeto. Por ahora, no veo que pases ningún identificador a su constructor y quizás todos los eventos se insertan con el mismo valor deid
. - Si no te importa generar ID por ti mismo, puedes agregar la configuración de
AUTOINCREMENT
a tu definición de columnaKEY_ID
. De esta manera, el campoKEY_ID
se llenará automáticamente y cada fila tendrá su propio valor único. Una vez allí, no olvides eliminar la adición deKEY_ID
aKEY_ID
por ti mismo.
Trate de comprobar si el ID ya existe. Si es verdadero, no inserte, porque ya tiene la fila con este ID.
Tuve el mismo problema y el problema fue que olvidé agregar db.execSQL(YOUR_TABLE);
en mi DbHelper
haga que la columna id sea un autoincremento de enteros y no coloque el valor de id en valores de contenido.