java - SQLiteDatabase.rawQuery 不使用准备好的语句返回正确的结果

标签 java sql android sqlite prepared-statement

我的准备好的 SQL 语句有一个奇怪且无法解释的错误,它没有提供与 noprepared 语句相同的结果。

这两个版本不应该返回相同的结果吗?

准备好的版本(结果错误):

sb.append(" WHERE c.deck_id=? AND c.next_date < ? AND c.next_date > 0 AND c.active > 0 AND c.deck_level=?");
...
return db.rawQuery(sb.toString(), new String[] { Long.toString(deckId)
, Long.toString(now), Long.toString(level)});

非准备版本(按预期工作,结果正确):

sb.append(" WHERE c.deck_id=").append(deckId)
.append(" AND c.next_date<").append(now)
.append(" AND c.next_date > 0 AND c.active > 0 AND c.deck_level=").append(level);
...
return db.rawQuery(sb.toString(), null);

prepart语句版本哪里出错了?

更新 我为这两个版本制作了额外的日志。

Log.d(TAG, "selectionArgs1:<em>" + Long.toString(deckId) + "</em>"+Long.toString(now)+ "<em>"+Long.toString(level)+ "</em>");
输出:selectionArgs1:*5*1294429481330*5* (所以:源代码中不显示 * 吗?)

StringBuffer d = new StringBuffer("selectionArgs2:<em>");
d.append(deckId).append("</em>").append(now).append("<em>").append(level).append("</em>");
Log.d(TAG, d.toString());
输出:selectionArgs2:*5*1294429481330*5*

最佳答案

我怀疑它与 type affinity 有关,但我无法像您描述的那样完全重现该问题。

亲和行为会影响比较表达式,所以'措手不及'

next_date < 12345678

可能不等同于“准备好的”:

next_date < '12345678'

请注意“rawQuery”绑定(bind)应用的隐含字符串数据类型 - rawQuery* javadoc 说:

The values will be bound as Strings.

我试图用 next_date INTEGER 字段编写一个测试用例,但没有成功。但是,如果该字段未键入,如:

CREATE TABLE cards ( next_date );

INSERT INTO cards SELECT 1234;
INSERT INTO cards SELECT '1234';

SELECT 'int', typeof( next_date ), next_date FROM cards WHERE next_date < 1234;
SELECT 'str', typeof( next_date ), next_date FROM cards WHERE next_date < '1234';

然后可以看到不同的亲和行为——结果是:

str|integer|1234

(也许这是评论,但格式化为答案更容易阅读。)

*http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#rawQuery(java.lang.String,%20java.lang.String[])

关于java - SQLiteDatabase.rawQuery 不使用准备好的语句返回正确的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4610083/

相关文章:

java - 如何在 Eclipse 中从 MoDisco java 模型生成 java 代码?

Java ListView 类?

sql - SQL如果可能,将值转换为int,如果不可能,则将值设置为0

PHP和MySQL多对多问题

java - 如何在线程和 GUI 之间进行通信

java - 触发垃圾收集以衡量 Web 应用程序的性能

mysql - 这个mysql语法有什么错误?

java - ArrayList<对象> 到 ArrayList<字符串>

Android:以编程方式更改字符串资源

android - 选择图像时无法解码流