it-swarm.com.de

UNIQUE-Einschränkung fehlgeschlagen: SQLite-Datenbank: Android

Ich versuche, Werte in die Tabelle einzufügen. Es wird jedoch nur ein Wert eingefügt. Beim Versuch, neue Werte einzufügen, wird in log cat ein Fehler angezeigt. 

Log Katzenausstellungen:

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)

Es zeigt einen Fehler in diesen beiden Zeilen beim Einfügen der Zeile.

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;
    }
}

Wie löse ich das?

26
user5669913

Ihr Code verstößt wahrscheinlich gegen die Eindeutigkeitseinschränkung des Primärschlüssels für ein KEY_ID-Feld.

Zwei mögliche Lösungen sind:

  1. Stellen Sie sicher, dass Ihre EventData.getId() eindeutige Werte pro Objekt zurückgibt. Im Moment sehe ich nicht, dass Sie einen Bezeichner an den Konstruktor übergeben, und möglicherweise werden alle Ereignisse mit demselben Wert für id eingefügt.
  2. Wenn Sie keine eigenen IDs generieren möchten, können Sie die AUTOINCREMENT-Einstellung zu Ihrer KEY_ID-Spaltendefinition hinzufügen. Auf diese Weise wird das KEY_ID-Feld automatisch gefüllt und jede Zeile hat ihren eigenen eindeutigen Wert. Vergessen Sie nicht, das Hinzufügen von KEY_ID zu ContentValues selbst zu entfernen.
23
Mateusz Herych

Für Entwickler, die Room Persistence Library verwenden. Sie können verwenden 

@Insert(onConflict = OnConflictStrategy.REPLACE)  // or OnConflictStrategy.IGNORE

in DAO nach Dokumentation einfügen

30
Dasser Basyouni

Die Tabelle hat eine eindeutige Einschränkung. Das bedeutet, dass nur eine Zeile mit einem angegebenen ID-Wert vorhanden sein kann. Wenn Sie versuchen, einige Werte für eine Zeile zu ändern, verwenden Sie UPDATE und nicht INSERT. Wenn Sie versuchen, diese Zeile hinzuzufügen, müssen Sie entweder eine andere, eindeutige ID vergeben oder Sie müssen die bereits vorhandene Zeile zuerst löschen. Welches davon die richtige Antwort ist, hängt davon ab, was Ihre App macht.

7
Gabe Sechan

Prüfen Sie, ob die ID bereits existiert. Wenn ja, nicht einfügen, da Sie bereits die Zeile mit dieser ID haben.

4
Kai Wang

Wenn Sie Raum verwenden, sollten Sie anstelle von @PrimaryKey@PrimaryKey(autoGenerate = true) verwenden.

und machen Sie Ihre ID-Variable optional:

@Entity(tableName = "contact_table") data class Contact(@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") var id: Long?, @ColumnInfo(name = "name") val name: String, @ColumnInfo(name = "phone") val phone: String)

übergeben Sie dann beim Hinzufügen eines neuen Elements null als ID. insert func gibt eine neue ID zurück und fügt sie Ihrem Objekt hinzu

val contact = Contact(null, name, phone)
contact.id = ContactRoomDatabase.getDatabase().contactDao().insert(contact)
2
user155

machen Sie die ID-Spalte mit der ID-Ganzzahl automatisch und fügen Sie den ID-Wert nicht in die Inhaltswerte ein.

1
Vickie Kangare

Mein Fehler war, ich habe versucht, die ID-Spalte zu füllen, obwohl sie bereits als INTEGER PRIMARY KEY AUTOINCREMENT definiert wurde.

1
Sam

Ursprünglich habe ich den neuen, einzigartigen Zwangskind des alten eingesetzt. Stellen Sie stattdessen sicher, dass Ihre aktuelle eindeutige Spalte zuerst steht:

CREATE TABLE TEST (client_id TEXT unique, remote_id INT unique)

Ich hatte das gleiche Problem und das Problem war, dass ich vergessen habe, db.execSQL(YOUR_TABLE); in meiner DbHelper hinzuzufügen.

0
EAMax