好的。。。我很纠结于这件事。我找了很多,甚至在斯塔克弗流,但我没有找到任何东西来解决我的问题。问题是:我试图更新数据库中的一列,但它总是出错,而且不起作用,我甚至不知道问题出在哪里。
我尝试过使用SQLiteDatabase.update(),但不起作用,现在使用execSQL(String);同样的错误。
所以我要展示我的代码,如果有人知道问题出在哪里…请帮帮我。
public void AbreouCriaBD() {
try {
String nomeBanco = "Usuarios";
dataBase = openOrCreateDatabase(nomeBanco, MODE_WORLD_WRITEABLE, null);
String sql = "CREATE TABLE IF NOT EXISTS usuario" +
"(id INTEGER PRIMARY KEY, login TEXT, senha TEXT, saldoBanco float, saldoCredito float, saldoFuturos float)";
dataBase.execSQL(sql);
} catch(Exception erro) {
Alerta("Erro BD","BD Não criado");
}
}
public void UpdateBDPrincipal(double saldo) {
String saldoString = String.valueOf(saldo);
try {
dataBase.execSQL("UPDATE usuario SET 'saldoBanco'="+ saldoString +"WHERE 'login'= cristiano");
} catch(Exception error) {
Alerta("Erro","Erro no UPDATE");
}
}
public void Alerta(String title,String message) {
AlertDialog.Builder Sucesso = new AlertDialog.Builder(TelaSaldoCredito.this);
Sucesso.setTitle(title);
Sucesso.setMessage(message);
Sucesso.setNeutralButton("ok", null);
Sucesso.show();
}
它就是不起作用。。。请随便什么。。。
08-16 15:36:24.729: W/System.err(10855): java.lang.NullPointerException
08-16 15:36:24.739: W/System.err(10855): at com.bunchoffat.financejournal.TelaSaldoCredito.UpdateBDPrincipal(TelaSaldoCredito.java:121)
08-16 15:36:24.739: W/System.err(10855): at com.bunchoffat.financejournal.TelaSaldoCredito$1.onClick(TelaSaldoCredito.java:62)
08-16 15:36:24.739: W/System.err(10855): at android.view.View.performClick(View.java:2579)
08-16 15:36:24.739: W/System.err(10855): at android.view.View$PerformClick.run(View.java:9246)
08-16 15:36:24.739: W/System.err(10855): at android.os.Handler.handleCallback(Handler.java:587)
08-16 15:36:24.739: W/System.err(10855): at android.os.Handler.dispatchMessage(Handler.java:92)
08-16 15:36:24.739: W/System.err(10855): at android.os.Looper.loop(Looper.java:130)
08-16 15:36:24.739: W/System.err(10855): at android.app.ActivityThread.main(ActivityThread.java:3735)
08-16 15:36:24.739: W/System.err(10855): at java.lang.reflect.Method.invokeNative(Native Method)
08-16 15:36:24.739: W/System.err(10855): at java.lang.reflect.Method.invoke(Method.java:507)
08-16 15:36:24.759: W/System.err(10855): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
08-16 15:36:24.759: W/System.err(10855): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:662)
08-16 15:36:24.759: W/System.err(10855): at dalvik.system.NativeStart.main(Native Method)
正如我所看到的,错误是NullPointerException。。。但是我不知道为什么。。。数据库上有数据,我很确定,因为我可以登录系统,密码在数据库上。。。那么…我在这里错过了什么?
您的查询中有一个错误。添加saldoString后,WHERE语句之前没有空格。
public void UpdateBDPrincipal(double saldo){
String saldoString = String.valueOf(saldo);
try{
dataBase.execSQL("UPDATE usuario SET 'saldoBanco'="+ saldoString +" WHERE 'login'= cristiano");
} catch(Exception error) {
Alerta("Erro","Erro no UPDATE");
}
}
附言:以这种方式构建SQL字符串时要小心,它可能容易受到SQL注入攻击。在这种特殊情况下,它"有效",因为萨尔多是一个替身。但是,如果它是一个字符串,那么在不转义或不将字符串放入''
的情况下创建字符串是非常危险的
更新:此外,请不要抑制异常输出,这会使跟踪错误变得更加困难。
try {
} catch(Exception error) {
error.printStackTrace(); // Print error to the log
Alerta("Erro","Erro no UPDATE");
}
然后使用logcat读取Android日志。如果您正在使用Eclipse进行调试,则Logcat是添加的窗口之一。如果你没有使用eclipse或使用eclipse测试它,请在命令行中运行"adb-logcat"(你的智能手机必须通过USB连接到你的计算机)。
更新2:下面是一个关于如何使用SQLiteOpenHelper的示例。
public class MyServiceProvider extends ContentProvider {
private static final String TABLE_NAME = "usuario";
private SQLiteDatabase db;
@Override
public boolean onCreate() {
// Initialize the database and assign it to the private variable
MyDatabaseHelper sqlHelper = new MyDatabaseHelper(getContext());
db = sqlHelper.getReadableDatabase();
return (db == null)?false:true;
}
public void UpdateBDPrincipal(double saldo){
String saldoString = String.valueOf(saldo);
try {
dataBase.execSQL("UPDATE usuario SET 'saldoBanco'="+ saldoString +"WHERE 'login'= cristiano");
} catch(Exception error) {
Alerta("Erro","Erro no UPDATE");
}
}
}
class MyDatabaseHelper extends SQLiteOpenHelper {
private static final String LOG_TAG = "MyAppTag";
private static final String DB_NAME = "Usuarios";
private static final String TABLE_NAME = "usuario";
private static final int DATABASE_VERSION = 2;
public MyDatabaseHelper(Context context){
super(context, DB_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS usuario" +
"(id INTEGER PRIMARY KEY, login TEXT, senha TEXT, saldoBanco float, saldoCredito float, saldoFuturos float)";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Here you can perform updates when the database structure changes
// Begin transaction
db.beginTransaction();
try {
if(oldVersion<2){
// Upgrade database structure from Version 1 to 2
String alterTable = "ALTER ....";
db.execSQL(alterTable);
Log.i(LOG_TAG,"Successfully upgraded to Version 2");
}
db.setTransactionSuccessful();
} catch(Exception ex){
ex.printStackTrace();
} finally {
// Ends transaction
// If there was an error, the database won't be altered
db.endTransaction();
}
}
}
通过这种方式,您可以在数据库创建和加载以及查询的构建或处理方式之间有一个清晰的抽象(即,通过覆盖更新、删除、查询方法)。
编辑:SQLiteDatabase.update()
:的使用
private String userName = "cristiano";
ContentValues values = new ContentValues();
values.put("saldoBanco", 150.23);
// define the WHERE clause but do not directly concat values into the string
// Use question marks (?) as place holders.
String whereClause = "WHERE login = ?";
// define a list of args. For each '?' used in WHERE clause, add one element to the array
String[] whereArgs = new String[] { userName };
int numRowsUpdated = db.update(TABLE_NAME, values, whereClause, whereArgs);
执行时,问号将替换为whereArgs
中的元素。第一个问号将被whereArgs
的第一个元素替换,第二个问号将由第二个whereArgs
等替换。
通过这种方式,您可以轻松地创建where子句,并避免SQL注入漏洞的风险。