2012-05-10 82 views
3

我有一个与sqlite数据库的android应用程序。有时,当我更新我的表,我得到以下错误:android sqlite约束更新失败

error code 19: constraint failed android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed 

我没有看到哪个约束可能会失败,因为我没有外键,我不插入一个NULL值。

表:

"CREATE TABLE HIST (" + 
    "_id INTEGER PRIMARY KEY AUTOINCREMENT," + 
    "CL TEXT UNIQUE, " + 
    "ACOUNT INTEGER DEFAULT 0, " + 
    "HS INTEGER DEFAULT 0," + 
    "EX INTEGER DEFAULT 0," + 
    "LU INTEGER NOT NULL DEFAULT 0," + 
    "LT REAL NOT NULL DEFAULT 0);";  

更新代码:

SQLiteStatement updateTempStatement = db.compileStatement("UPDATE HIST " + 
      " SET LT=? WHERE _id=?"); 

    Cursor c = null; 

    c = db.rawQuery(QUERY_SQL, new String[] { hs?"1":"0" }); 

    Info[] result = null; 

    if (c.getCount() > 0) { 
     result = new Info[c.getCount()]; 

     int i = 0; 
     int idInd = c.getColumnIndex("_id"); 
     int cInd = c.getColumnIndex("CL"); 
     int hsuInd = c.getColumnIndex("HSU"); 
     int ltInd = c.getColumnIndex("LT"); 

     db.beginTransaction(); 
     try { 
      while (c.moveToNext()) { 
       result[i] = new Info(c.getString(cInd), 
         c.getFloat(hsuInd), 
         c.getFloat(ltInd)); 

       updateTempStatement.bindDouble(1, result[i].getLt()); 
       updateTempStatement.bindLong(2, c.getLong(idInd)); 
       updateTempStatement.execute(); 

       i = i + 1; 
      } 
      db.setTransactionSuccessful(); 
     } 
     finally { 
      db.endTransaction(); 
     } 

    } 

    c.close(); 

    updateTempStatement.close(); 

唯一的例外是关于updateTempStatement.execute();行了。

我看到的唯一约束是"NOT NULL",但方法Info.getlt()返回一个浮点型元素,因此它不能为NULL。

还有其他想法吗?

+0

您无法更新您的主键。 – Dhruvisha

+0

@Dhruvisha我没有更新我的主键。我的主键是_id,我正在更新字段LT。 – Ran

+0

检查字段LT。您正在更新的是真正的价值吗? – Dhruvisha

回答

1

1)你的表的一个重要限制是主键。尝试更新主键或将重复主键插入到表中时会发生此错误。

2)尝试:

c.moveToFirst(); 
do {  
    //... 
} while (c.moveToNext()); 

3)你正确的参数传递给信息(......)?

4)您是否在Info(...)中正确赋值?

+0

我没有更新我的主键,我没有插入任何东西到表中。 – Ran

+0

您可以在Android中清除您的应用的数据并重新创建HIST。也许它在您以前的应用程序版本中定义了它的旧结构。 – breceivemail

0

仔细检查result[i].getLt()真的从来没有返回null

+0

它返回一个浮点型变量(不是浮点型),它不能为空。 – Ran

0

你应该叫updateTempStatement.execute(); oustside循环。

+0

为什么?我有一个游标中每一行的更新。 – Ran

+0

因为这个execute()方法需要时间并且使用更多的资源。所以你可能不会收到这些不需要的错误。 – AnkitRox

1

首先,这是一个有效的列?

int hsuInd = c.getColumnIndex(“HSU”);

看着你的表格,该列标记为HS。

其次,使用更新功能会不会更好?

ContentValues values = new ContentValues(); 
values.put("LT", (Double) result[i].getLt()); 
int result = db.update("HIST", values, "_id = " + c.getInt("_id"), null); 
+0

HSU是查询中表达式的计算列。我相信使用SQLiteStatement更有效率(不需要每次重新构建查询,查看SQLiteDatabase的源代码)。 – Ran