【问题标题】:Android: SQLite Constraint failed issueAndroid:SQLite 约束失败问题
【发布时间】:2016-07-21 02:26:31
【问题描述】:

在我的应用程序中,我使用的是 SQLite 数据库。在我的一张表中插入数据时,我遇到了“SQLite 异常:错误 19”的奇怪问题。第一次插入数据,但是当我再次尝试插入数据时,它会抛出异常。

我的创建表查询:

"CREATE TABLE Tickets ("
            + "ID integer PRIMARY KEY NOT NULL,"
            + " UID varchar(40) NOT NULL DEFAULT 'not available'," + " OrderID int NOT NULL,"
            + " CarrierTicketNum varchar(15) NOT NULL,"
            + " TicketTypeID int NOT NULL," + " TankTypeID int NULL,"
            + " ProductObsGravity numeric NULL DEFAULT 0,"
            + " ProductHighTemp numeric NULL DEFAULT 0,"
            + " ProductLowTemp numeric NULL DEFAULT 0,"
            + " ProductObsTemp numeric NULL DEFAULT 0,"
            + " ProductBSW numeric NULL DEFAULT 0");

插入查询:

public void insertTank(int OrderID, int TicketTypeID,
        String CarrierTicketNum, String TankNum, int TankTypeID,
        Double ProductObsTemp, Double ProductObsGravity, Double ProductBSW,
        Double GrossBarrels, Double NetBarrels) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("OrderID", OrderID);
    values.put("CarrierTicketNum", CarrierTicketNum);
    values.put("TankNum", TankNum);
    values.put("TicketTypeID", TicketTypeID);
    values.put("TankTypeID", TankTypeID);
    values.put("ProductObsTemp", ProductObsTemp);
    values.put("ProductObsGravity", ProductObsGravity);
    values.put("ProductBSW", ProductBSW);
    values.put("GrossBarrels", GrossBarrels);
    values.put("NetBarrels", NetBarrels);
    //try {
        db.insertOrThrow("Tickets", null, values);
    /*} catch (SQLiteException sqle) {
        Log.d(TAG, "SQLITException: " + sqle.getMessage());
    }*/
    db.close(); // Closing database connection
}

以下是日志详情:

09-08 13:54:57.610: E/AndroidRuntime(5713): FATAL EXCEPTION: main
09-08 13:54:57.610: E/AndroidRuntime(5713): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.database.sqlite.SQLiteStatement.native_executeInsert(Native Method)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:113)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1718)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1617)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at com.dzo.dispatchcrude.driverapp.datalayer.DatabaseHandler.insertTank(DatabaseHandler.java:736)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at com.dzo.dispatchcrude.driverapp.NetBarrelActivity$1.onClick(NetBarrelActivity.java:103)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.view.View.performClick(View.java:3511)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.view.View$PerformClick.run(View.java:14110)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.os.Handler.handleCallback(Handler.java:605)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.os.Handler.dispatchMessage(Handler.java:92)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.os.Looper.loop(Looper.java:137)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at android.app.ActivityThread.main(ActivityThread.java:4424)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at java.lang.reflect.Method.invokeNative(Native Method)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at java.lang.reflect.Method.invoke(Method.java:511)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-08 13:54:57.610: E/AndroidRuntime(5713):     at 
dalvik.system.NativeStart.main(Native Method)

阅读了几乎数量的帖子,但没有得到太多帮助。

【问题讨论】:

  • 所以你想更新已经存在的数据?
  • 不,我想每次都插入新数据。语法有什么问题吗?
  • 所以你只需要插入一个新行?
  • 是的,我想插入新行
  • 在插入语句上放一个断点。检查values。它是否包含任何空值?

标签: android sqlite


【解决方案1】:

有两种方法可以解决您的问题。

第一:

PRIMARY KEY 声明为autoincrement

第二:

尝试插入新行时,provide different/unique ID 表示新行。

要对其进行测试,请在再次运行您的应用之前DELETE DATABASE

解决方案: 这一行应该是:

+ "ID integer PRIMARY KEY AUTOINCREMENT," 

而不是

+ "ID integer PRIMARY KEY NOT NULL,"

【讨论】:

  • 在 sqlite 中,不需要主键的自动增量,对吧?虽然,我尝试过但没有成功。
  • 需要输入NULL吗?也许,这可能是问题所在。
  • 如果你放NOT NULL,你不能放非空值,但如果你什么都不放,你甚至可以放空值或非空值。
  • 但是你的错误不是这个。您的错误可能是您试图在同一行中插入两次值(所以相同的 ID)。尝试删除您的数据库并使用autoincrement 作为ID 重新运行应用程序。它应该工作
  • 我试过了,就像你说的那样。我删除了数据库,并使用自动增量重新运行我的应用程序。该应用程序在第二次插入时崩溃了。
【解决方案2】:
android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed

您的约束失败,因为您违反了字段上的约束,例如将空值传递到您在创建表时声明为非空的列。

我认为"ID integer PRIMARY KEY NOT NULL," 是您的问题,请确保它是autoincrement 并且其他值不为空,因为您设置了 Not null 约束。

【讨论】:

  • 但是,我没有在主键中传递任何东西。我也尝试了自动增量。
  • 但是其中一个字段 UID(请参阅创建表查询)将在同步时从服务器更新,我不能放任何东西。这可能是问题的原因吗?
  • 检查你要插入的数据,确保两条记录的key不同。
  • 我没有看到任何问题,除了这里有两个相同键的记录。
【解决方案3】:

如果您使用 ID 作为 int 值而不是

"ID 整数 PRIMARY KEY AUTOINCREMENT"

而不是

"ID 整数 PRIMARY KEY NOT NULL"

如果您使用 ID 作为字符串值而不是

使用下面的行插入值 db.insertWithOnConflict(TABLE_NAME, null,values,SQLiteDatabase.CONFLICT_IGNORE);

(其中 values 是 ContentValues 对象的对象)

而不是

db.insert(TABLE_NAME, null, values);

继续编码....微笑...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 2013-01-20
    相关资源
    最近更新 更多