【问题标题】:Android SQLite Database Unique constraint failed with composite primary keyAndroid SQLite 数据库唯一约束因复合主键而失败
【发布时间】:2018-03-21 10:07:39
【问题描述】:

当我尝试使用复合主键保存在表中时,当相同的Event.Player id 与相同的Event.Game id 一起使用时,我收到错误 UNIQUE constraint failed,但由于它是一个 4 复合主键不应该给问题。

创建表代码:

private static final String CREATE_TB_EVENT = "CREATE TABLE IF NOT EXISTS "+TABLE_EVENT+" ( GAME INTEGER NOT NULL, " +
        "PLAYER INTEGER NOT NULL, TYPE INTEGER NOT NULL, MINUTE INTEGER NOT NULL, PRIMARY KEY ( GAME, PLAYER, TYPE, MINUTE ), " +
        "FOREIGN KEY ( GAME ) REFERENCES "+TABLE_GAME+" ( IDGAME ), " +
        "FOREIGN KEY ( PLAYER ) REFERENCES "+TABLE_PLAYER+" ( IDPLAYER ) )";

当我首先更新TABLE_GAME 中的记录时发生错误(IDGAME 没有被触及),然后我删除TABLE_EVENT 中的所有行与IDGAME final String DELETE_EVENTS = "DELETE FROM "+TABLE_EVENT+" WHERE GAME = "+game.getId(); db.execSQL(DELETE_EVENTS);

然后我调用这个方法,在这个方法中我违反了唯一约束

public boolean saveEvents(ArrayList<Event> events, int gameID) {
    if(events == null)
        return false;
    try {
        SQLiteDatabase db = getWritableDatabase();
        Log.v(TAG, getTableAsString(db, TABLE_EVENT));
        ContentValues cv = new ContentValues();
        for(Event e : events) {
            cv.put("GAME",gameID);
            cv.put("PLAYER",e.getIdPlayer());
            cv.put("TYPE",e.getType());
            cv.put("MINUTE",e.getMinute());
            db.insert(TABLE_EVENT, null, cv);
            Log.v(TAG, getTableAsString(db, TABLE_EVENT));
        }
        db.close();
        return true;
    } catch (SQLiteException | NullPointerException ex) {
        Log.e(TAG, ex.getMessage());
        return false;
    }
}

错误:Error inserting MINUTE=90 PLAYER=4 TYPE=2 GAME=54 UNIQUE constraint failed: Event.GAME, Event.PLAYER (code 1555)

当我登录上面的方法打印TABLE_EVENT时,我得到:

Table Event: empty

Table Event: GAME: 54 PLAYER: 4 TYPE: 1 MINUTE: 23

Table Event: GAME: 54 PLAYER: 4 TYPE: 1 MINUTE: 23
             GAME: 54 PLAYER: 5 TYPE: 2 MINUTE: 45

Table Event: GAME: 54 PLAYER: 4 TYPE: 1 MINUTE: 23
             GAME: 54 PLAYER: 5 TYPE: 2 MINUTE: 45
             GAME: 54 PLAYER: 10 TYPE: 1 MINUTE: 23

Table Event: GAME: 54 PLAYER: 4 TYPE: 1 MINUTE: 23
             GAME: 54 PLAYER: 5 TYPE: 2 MINUTE: 45
             GAME: 54 PLAYER: 10 TYPE: 1 MINUTE: 23

如您所见,最后两个输出是相同的,因为它没有添加新行

GAME=54 PLAYER=4 TYPE=2 MINUTE=90

我在SQL Fiddle 尝试过,一切正常

我错过了什么?

【问题讨论】:

  • 看起来你在桌子上对“游戏”和“玩家”列有一个独特的约束。不过,我在您的表定义中没有看到它。该表是否可能已经存在,并且它具有添加的约束?
  • 没错,好像有一个定义 UNIQUE(game,player) 但没有
  • 您是否可以尝试删除该表,然后使用您发布的创建代码重新创建它?或者只是检查 sqlite 表是否有特定的约束?您的创建表仅在表不存在时执行,因此可能已经存在具有该添加约束的表版本

标签: android sql sqlite unique-constraint composite-primary-key


【解决方案1】:

我解决了这个问题。由于谷歌的自动备份,我的表有一个现有的副本,这就是为什么它一直说UNIQUE constraint failed。 解决方案进入Android Manifest 并设置

allowBackup = "false"

【讨论】:

    猜你喜欢
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多