2012-05-10 88 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