如何将值绑定到SQLiteStatement以进行插入查询?

时间:2017-01-29 13:32:31

标签: android sqlite sql-insert

使用SQLiteStatement的插入代码通常如下所示,

String sql = "INSERT INTO table_name (column_1, column_2, column_3) VALUES (?, ?, ?)";
SQLiteStatement statement = db.compileStatement(sql);

int intValue = 57;
String stringValue1 = "hello";
String stringValue2 = "world";   
// corresponding to each question mark in the query
statement.bindLong(1, intValue); 
statement.bindString(2, stringValue1); 
statement.bindString(3, stringValue2);

long rowId = statement.executeInsert();

现在这个工作完全正常,但我在这里找到的问题是我必须非常小心将正确的数据绑定到相应的索引。简单的索引交换会给我一个错误。

另外,让我们说将来column_2从表中删除,然后我必须在column_2索引之后更改所有索引,否则该语句将无效。如果我只有3列,这似乎微不足道。想象一下,如果一个表有10-12(或更多)列,第2列被删除。我将不得不更新所有后续列的索引。整个过程似乎效率低下且容易出错。

是否有一种优雅的方式来处理所有这些

编辑:为什么我要使用SQLiteStatement?检查一下:Improve INSERT-per-second performance of SQLite?

2 个答案:

答案 0 :(得分:2)

可以使用ContentValues

完成插入
ContentValues cv = new ContentValues();
cv.put("column_1", 57);
cv.put("column_2", "hello");
cv.put("column_3", "world");
long rowId = db.insertOrThrow("table_name", null, cv);

但在一般情况下,最正确的方法是使用named parameters。但是,Android数据库API不支持这些。

如果您真的想使用SQLiteStatement,请编写自己的辅助函数,从列列表构建它,并负责将其与实际数据进行匹配。您还可以编写自己的bindXxx()包装器,将先前保存的列名映射到参数索引。

答案 1 :(得分:0)

您可以将ContentValues与beginTransaction一起使用到SQLite中,这非常简单,而且比预备语句更快

为此,您必须先创建ContentValues数组,或者在循环中创建Content value对象。并传入插入方法。这个解决方案解决了你们两个问题。

mDatabase.beginTransaction();
    try {
        for (ContentValues cv : values) {
            long rowID = mDatabase.insert(table, " ", cv);
            if (rowID <= 0) {
                throw new SQLException("Failed to insert row into ");
            }
        }
        mDatabase.setTransactionSuccessful();
        count = values.length;
    } finally {
        mDatabase.endTransaction();
    }