2012-10-17 45 views
1

我的代碼如下,但它崩潰了我的應用程序。我對db的工作還很新,但看起來很合理。任何跡象表明爲什麼這可能不起作用?Android SQLite試圖更新一個字段

public void updateLevel(String level){ 
      mDb.rawQuery("UPDATE "+ DATABASE_TABLE + " SET " + KEY_CUR_LEVEL + " = " + level + " WHERE " + KEY_NAME + " = Default", null); 
     } 

回答

2

您的Default被解釋爲列名;如果它是一個字符串,則必須使用'Default'

爲避免這樣的格式化問題,建議使用參數,這些參數在SQL命令中寫爲?。他們從rawQuery的第二個參數(或其他SQL函數的類似參數)的相應條目中獲得它們的值。 這比在字符串周圍放置'容易,記住要在字符串內部跳出',並且使得使用具有控制字符的字符串成爲可能。

mDb.rawQuery("UPDATE "+ DATABASE_TABLE + 
      " SET " + KEY_CUR_LEVEL + " = " + level + 
      " WHERE " + KEY_NAME + " = ?", 
      new String[] { "Default" }); 
+0

完美。你的第一個建議起作用了。我不確定你的意思是使用參數。謹慎解釋? – EGHDK

+0

RE「使用參數」 - 請參閱此處:http://www.sqlite.org/lang_expr.html#varparam – CJBS

+0

爲了避免SQL注入,我建議參數化'level' – CJBS

1

我看到兩個問題:

1)使用rawQuery由於SQL注入discuoraged。如果可能的話使用SQLiteDatabase query

2)如果列的類型是varchar,則值應該是單引號。

例子:

mDb.rawQuery("UPDATE "+ DATABASE_TABLE + " SET " + KEY_CUR_LEVEL + " = '" + level + "' WHERE " + KEY_NAME + " = 'Default'", null); 

注:以上查詢是手工輸入的可能有語法錯誤。

+0

APpreciate輸入,但由於我沒有從用戶的文本,我不認爲我必須擔心SQL注入。 – EGHDK

+0

@EGHDK:SQL注入不僅僅是因爲用戶輸入,它可能是如果任何特殊字符已存儲在該密鑰中的情況。如果您對該問題不太敏感,則可以忽略並繼續進行第2點修復。 – kosa

1

我發現使用update方法不太容易出現人爲錯誤。

ContentValues cv = new ContentValues(); 
cv.put(KEY_CUR_LEVEL, level); 

mDb.update(DATABASE_TABLE, cv, "? = ?", new String[] { KEY_NAME, "Default"}); 
+1

列名稱不能用作參數。 –

+0

+1和CL和Vyrx。我不會使用佔位符(?)作爲列名,但通常,我還發現使用這部分API優於'rawQuery()'。 – spaaarky21

相關問題