web-dev-qa-db-ja.com

UNIQUE制約の失敗:sqliteデータベース:android

テーブルに値を挿入しようとしています。ただし、挿入される値は1つだけです。新しい値を挿入しようとすると、log catでエラーが発生します。

ログ猫ショー:

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)

行の挿入中にこれらの2行にエラーが表示されます。

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

これを解決するには??

32
user5669913

あなたのコードは、おそらくKEY_IDフィールドの主キーの一意性制約に違反しています。

次の2つの解決策があります。

  1. EventData.getId()がオブジェクトごとに一意の値を返すことを確認してください。現時点では、コンストラクタに識別子を渡すことはなく、おそらくすべてのイベントが同じid値で挿入されます。
  2. 自分でIDを生成する必要がない場合は、AUTOINCREMENT設定をKEY_ID列定義に追加できます。これにより、KEY_IDフィールドが自動的に入力され、各行に独自の一意の値が設定されます。一度、KEY_IDContentValuesに自分で追加することを忘れないでください。
26
Mateusz Herych

Room Persistence Library を使用する開発者向け。使用できます

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

ドキュメントの挿入 に従ってDAOで

44
Dasser Basyouni

テーブルには一意の制約があります。つまり、特定のID値を持つ行は1つしか存在できません。行の値の一部を変更しようとしている場合は、INSERTではなくUPDATEを使用します。この行を追加しようとしている場合は、別の一意のIDを指定するか、最初に既存の行を削除する必要があります。どちらが正しい答えであるかは、アプリが何をしているかによって異なります。

7
Gabe Sechan

IDが既に存在するかどうかを確認してください。 trueの場合、すでにこのIDの行があるため、挿入しないでください。

6
Kai Wang

id column id integer autoincrementを作成し、id値をコンテンツ値に入れないでください。

2
Vickie Kangare

Roomを使用する場合、@PrimaryKeyの代わりに@PrimaryKey(autoGenerate = true)を使用する必要があります

id変数をオプションにします:

@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)

そして、新しいアイテムを追加するとき、nullをidとして渡し、insert funcは新しいidを返し、オブジェクトに追加します

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

私の間違いは、INTEGER PRIMARY KEY AUTOINCREMENTとして既に定義されているにもかかわらず、ID列を埋めようとしたことです。

1
Sam

私はもともと、古いものの新しいユニークな制約幼児を置きました。代わりに、現在の一意の列が最初であることを確認してください。

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

私は同じ問題を抱えていましたが、問題はDbHelperdb.execSQL(YOUR_TABLE);を追加するのを忘れたことです

0
EAMax