2012-10-17 49 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

相关问题