首页 > 解决方案 > 如何为sql使用准备好的语句?

问题描述

我试图在 android 中有一个 SQLite 数据库,但我有一个问题:

我正在尝试使用 id 0 更新“响应”列中的文本值。我遇到的第一个问题是我用于更新的字符串使用了撇号 (') 并且它有语法错误,因为 sql 关闭了字符串带着 '。所以我现在为此使用准备好的 sql 语句。现在的问题是返回的 long 给出了 -1,因此这意味着没有任何行受到影响。那么如何将当前字符串更新为 id=0 的行呢?

注意:第一个字符串也有一个 ' 但是是使用 addData 函数添​​加的,并且仅使用 db.insert 没有给出任何错误,这是问题所在,我应该用准备好的语句替换我的所有代码吗?

public boolean addData(String item) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL2, item);

    Log.d(TAG, "addData: Adding " + item + " to " + TABLE_NAME);
    long result = db.insert(TABLE_NAME, null, contentValues);

    //if date as inserted incorrectly it will return -1
    if (result == -1) {
        return false;
    } else {
        return true;
    }
}

public long updateData(String newName){
    SQLiteDatabase db = this.getWritableDatabase();

    String sql = "UPDATE json_response SET response=? WHERE ID='0'";
    SQLiteStatement statement = db.compileStatement(sql);

    statement.bindString(1, newName);  // matches second '?' in sql string
    long rowId = statement.executeInsert();
    return rowId;
}

标签: javaandroiddatabasesqliteprepared-statement

解决方案


我没有太多使用准备好的语句,所以我不能说为什么它不起作用,但为什么不使用db.update()方法呢?它以 ContentValues 作为参数,类似于 tour addData() 方法。试一试。

public int updateData(String newName){
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues cv = new ContentValues();
    cv.put("json_response",newName);

    int rows = db.update(TABLE_NAME, cv, "ID=0", null);
    return rows;
}

[编辑] update() 返回一个整数,表示受影响的行数,而不是受影响的行。请记住这一点,因为您的变量名称 rowId 暗示这不是您要查找的内容。

[编辑 2] 不,我可以看到的 addData() 方法没有问题。添加的撇号不会导致错误,因为 ContentValues 在将字符串值添加到数据库之前会对其进行参数化。基本上,在插入值时,所有类似 SQL 的语法都将被忽略,这对安全性来说非常有用。


推荐阅读