【问题标题】:android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed:android.database.sqlite.SQLiteConstraintException:唯一约束失败:
【发布时间】:2019-04-28 14:08:06
【问题描述】:

错误

 FATAL EXCEPTION: main
                                                                             Process: com.appmaster.akash.messageplus, PID: 14373
                                                                             android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: UserData.RecieversID (code 1555)
                                                                                 at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
                                                                                 at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:734)
                                                                                 at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
                                                                                 at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
                                                                                 at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1579)
                                                                                 at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1525)
                                                                                 at com.appmaster.akash.messageplus.Chat.mMessagesSent(Chat.java:918)
                                                                                 at com.appmaster.akash.messageplus.Chat.sendMessage(Chat.java:709)
                                                                                 at com.appmaster.akash.messageplus.Chat.access$900(Chat.java:76)
                                                                                 at com.appmaster.akash.messageplus.Chat$5.onClick(Chat.java:442)
                                                                                 at android.view.View.performClick(View.java:6256)
                                                                                 at android.view.View$PerformClick.run(View.java:24701)
                                                                                 at android.os.Handler.handleCallback(Handler.java:789)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:98)
                                                                                 at android.os.Looper.loop(Looper.java:164)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

插入

 MainData helper = new MainData(this); //Change the name to your Helper Class name
    SQLiteDatabase db = helper.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(KEY_ID, MessageRecieverId);
    contentValues.put(KEY_NAME, MessageRecieverName);
    contentValues.put(KEY_MESSAGES_SENT, 0);
    contentValues.put(KEY_MESSAGES_RECIEVED, 0);
    contentValues.put(KEY_TIME_SPENT, "");

    long returnVariable = db.insert(TABLE_USER_DATA,null,contentValues);
    if (returnVariable == -1) {
        Toast.makeText(getApplication(), "Nope", Toast.LENGTH_LONG).show();

插入没有问题,但更新时出现此错误

更新

 MainData helper = new MainData(this); //Change the name to your Helper Class name
    SQLiteDatabase db = helper.getWritableDatabase();int userData = 0;
    Cursor data2 = helper.getUserData();
    while (data2.moveToNext()) {
        userData = data2.getInt(data2.getColumnIndex("MessagesSent"));
    }
    ContentValues contentValues2 = new ContentValues();
    contentValues2.put(KEY_ID, MessageRecieverId);
    contentValues2.put(KEY_MESSAGES_SENT, userData+1);
    long returnVariable2 = db.update(TABLE_USER_DATA, contentValues2,null,null);
    if (returnVariable2 == -1) {
        Toast.makeText(getApplication(), "Nope", Toast.LENGTH_LONG).show();
        //-1 means there was an error updating the values
    } else {
        Toast.makeText(getApplication(),"uf", Toast.LENGTH_SHORT).show();
    }

有人知道为什么会这样吗? ..................................................... ..................................................... ................................................

【问题讨论】:

  • 因为你违反了数据库的约束。 UserData.RecieversID 列可能只包含您在更新时似乎在代码中忽略的唯一值。

标签: java android sql sqlite android-studio


【解决方案1】:

您很可能使用 id 列 (KEY_ID) 的值进行插入。此列的赔率定义为 INTEGER PRIMARY KEYINTEGER PRIMARY KEY AUTOINCREMENT

通常您不会为这样的列指定值,因为 SQLite 会分配唯一值(通常比分配的最高值大 1)。

如果您为此类列指定了一个值,并且表中的一行已经在该列中具有该值,则将违反 PRIMARY KEY 隐含的 UNIQUE 约束因为它违反了 PRIMARY KEY 必须是唯一的规则。

我建议您使用 :-

MainData helper = new MainData(this); //Change the name to your Helper Class name
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
//contentValues.put(KEY_ID, MessageRecieverId); //<<<<<<<<<< COMMENTED OUT (can delete the line)
contentValues.put(KEY_NAME, MessageRecieverName);
contentValues.put(KEY_MESSAGES_SENT, 0);
contentValues.put(KEY_MESSAGES_RECIEVED, 0);
contentValues.put(KEY_TIME_SPENT, "");

long returnVariable = db.insert(TABLE_USER_DATA,null,contentValues);
if (returnVariable == -1) {
    Toast.makeText(getApplication(), "Nope", Toast.LENGTH_LONG).show();

returnVariable 将是插入行时分配的 id 列 (KEY_ID) 的值。

  • 注意 id 列并不一定意味着该列被命名为 id,但由于它的定义方式,它是一个特殊的列。也就是说,通过指定 INTEGER PRIMARY KEY,该列实际上是通常隐藏的 rowid 列的别名(除非 TABLE 是使用 WITHOUT ROWID 短语定义的)。

阅读SQLite Autoincrement 会很有帮助。

【讨论】:

  • 但我想将数据更新到 KEY_ID = MessageRecieverId 的行
  • 因此,如果我使用随机 id 插入它,那么我将无法获取该行,因为没有外键,所以我必须只使用 ID 主键来识别
  • 您没有插入随机密钥。您让 SQLite 生成密钥 (id) (实际上 SQLite 无论如何都会这样做,而是通过定义别名使该值更容易获得)这将是唯一的,因此您可以如何 identify 任何行。从插入返回的值就是那个值。当您检索一行或多行(例如,从列表视图中)时,您将 id 包含在 Cursor 中,因此可以在单击项目时访问 id。
【解决方案2】:

看起来你犯了和我一样的新手错误。当使用 db.update 修改行值时,您不会通过将 KEY_ID 添加到 ContentValues 来指定哪一行。相反,您必须为此目的使用 where 子句。 where 子句是传递给 db.update 的参数之一。

说明:ContentValues 包含应用于选定行的列名/值对。 where 子句指示要选择的行。可以(并且很常见)选择多行。为 where 子句传递 null 会更新数据库中的每一行 - 所以要小心

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多