已达到数据库编译SQL语句缓存的最大大小

10

我的代码是

ContentValues values; 
values = new ContentValues();
        values.put(SQLHelper.EMPLOYEE_LPN, jsObj.getString("lpn"));
db.update(SQLHelper.EMPLOYEE_TABLE, values,
                "EMPLOYEE_LPN ='" + jsObj.getString("lpn") + "'",
                null);

在Log Cat中显示了一个警告。

08-31 15:19:45.297: WARN/Database(2868): Reached MAX size for compiled-sql statement cache for database /data/data/org.sipdroid.sipua/databases/test.db; i.e., 
NO space for this sql statement in cache: 
SELECT EMPLOYEE_NAME FROM eyemployee WHERE EMPLOYEE_LPN ='1169162'. 
Please change your sql statements to use '?' for bindargs, instead of using actual values

怎么解决这个问题?


3
请按照记录器的建议操作...请将您的 SQL 语句更改为使用“?”来绑定参数,而不是使用实际值。 - Rahul
@ Rahul,我使用db.update(SQLHelper.EMPLOYEE_TABLE, values, SQLHelper.EMPLOYEE_LPN + "=?", new String[]{jsObj.getString("lpn")})更新了数据库,但在日志中仍显示警告。 - jennifer
为什么你要将 EMPLOYEE_LPN 更新为 X,而且在你的 where 子句中也指定了 EMPLOYEE_LPN=X。这就像是“update table set x=1 where x=1”。 - Rahul
@ Rahul,请用示例代码解释一下,我不理解你的意思。 - jennifer
2
你想要更新 SQLHelper.EMPLOYEE_LPN 为 jsObj.getString("lpn"),那么在 where 子句中放置 SQLHelper.EMPLOYEE_LPN = jsObj.getString("lpn") 是没有意义的。这个查询是没有用处的。例如,你的查询看起来像 "update users set name='jennifer' where name='jennifer'"。 - Rahul
为什么缓存不会自动清除? - Someone Somewhere
2个回答

12

请看这里的8-3和8-4样例。

样例 8-3. 使用update方法

/**
 * Update a job in the database.
 * @param job_id         The job id of the existing job
 * @param employer_id    The employer offering the job
 * @param title          The job title
 * @param description    The job description
 */
public void editJob(long job_id, long employer_id, String title, String description) {
    ContentValues map = new ContentValues();
    map.put("employer_id", employer_id);
    map.put("title", title);
    map.put("description", description);
    String[] whereArgs = new String[]{Long.toString(job_id)};
    try{
        getWritableDatabase().update("jobs", map, "_id=?", whereArgs);
    } catch (SQLException e) {
        Log.e("Error writing new job", e.toString());
    }
}

以下是示例8-3代码的一些亮点:

示例8-4向您展示如何使用execSQL方法。
示例8-4. 使用execSQL方法

/**
 * Update a job in the database.
 * @param job_id         The job id of the existing job
 * @param employer_id    The employer offering the job
 * @param title          The job title
 * @param description    The job description
 */
public void editJob(long job_id, long employer_id, String title, String description) {
    String sql = 
        "UPDATE jobs " +
        "SET employer_id = ?, "+
        " title = ?,  "+
        " description = ? "+
        "WHERE _id = ? ";
    Object[] bindArgs = new Object[]{employer_id, title, description, job_id};
    try{
        getWritableDatabase().execSQL(sql, bindArgs);
    } catch (SQLException e) {
        Log.e("Error writing new job", e.toString());
    }
}

这条信息要求您使用SQL变量而不是SQL文字来作为参数。

每个SQL查询都会被解析,生成计划并存储在SQL语句缓存中。

具有相同文本的查询将从缓存中获取。

  --One query
SELECT * FROM Customers WHERE Id = @1   (@1 = 3)
SELECT * FROM Customers WHERE Id = @1   (@1 = 4)
SELECT * FROM Customers WHERE Id = @1   (@1 = 5)

具有不同文本(包括文字字面值)的查询无法在缓存中找到,因此会被(无意义地)添加到其中。

  --Three Queries.
SELECT * FROM Customers WHERE Id = 3
SELECT * FROM Customers WHERE Id = 4
SELECT * FROM Customers WHERE Id = 5

你确定8-4是一个有效的选择吗?bindArgs版本的execSQL的最新API文档说:“执行一个不是SELECT/INSERT/UPDATE/DELETE的单个SQL语句。”http://bit.ly/1gGhsUV - Dan J

2

今天我在搜索相关内容时,发现了这篇文档。

http://ormlite.com/docs/query-builder

这篇文档解决了我的问题。以下是来自上述链接的代码:

QueryBuilder<Account, String> queryBuilder =
  accountDao.queryBuilder();
Where<Account, String> where = queryBuilder.where();
SelectArg selectArg = new SelectArg();
// define our query as 'name = ?'
where.eq(Account.NAME_FIELD_NAME, selectArg);
// prepare it so it is ready for later query or iterator calls
PreparedQuery<Account> preparedQuery = queryBuilder.prepare();

// later we can set the select argument and issue the query
selectArg.setValue("foo");
List<Account> accounts = accountDao.query(preparedQuery);
// then we can set the select argument to another
// value and re-run the query
selectArg.setValue("bar");
accounts = accountDao.query(preparedQuery);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接