为什么SQLite中的RawQuery仅在没有问号的情况下才能工作(Kotlin)

时间:2019-06-16 05:53:11

标签: android sqlite kotlin

这是数据库funco(SQLite)中我的表your.db的结构和数据:

Id   Disp  Tp 
 1   Ball  2
 2   Light 1
 3   Sea   4 

这是我的代码:

var db = SQLiteDatabase.openDatabase(this.filesDir.path + 
          "/your.db",null, SQLiteDatabase.OPEN_READWRITE)
val c = db.rawQuery("Select Id, Disp, Tp From Funco Where Id<=2;",null)
var stat = c.moveToFirst()
var result=""
while (stat) {
    val mId = c.getInt(c.getColumnIndex("Id"))
    val mDisp = c.getString(c.getColumnIndex("Disp"))
    val mTp = c.getInt(c.getColumnIndex("Tp"))
    result += "$mId $mDisp $mTp | "
    stat = c.moveToNext()
}
c.close()
db.close()

result值:

 1   Ball  2 | 2   Light 1 |

如果我将第二行替换为

val c = db.rawQuery("Select ?, ?, ? From Funco Where  ?<=2;"
             ,arrayOf("Id","Disp","Tp","Id"))    

没有引发错误,但是光标为空!

为什么?

更新:

@tynn的答案是正确的。我认为文档很微妙。 我认为编译器应该抛出错误,而不仅仅是返回空游标。

以同样的风格,可以写作

val c = db.query("funco",arrayOf("Id","Disp","Tp"),"Id<=?",
arrayOf("2"),null,null,null)

但是下面的代码失败

val c = db.query("funco",arrayOf("Id","Disp","Tp"),"?<=?",
    arrayOf("id","2"),null,null,null)

1 个答案:

答案 0 :(得分:2)

the documentation所述:

  

selectionArgs 字符串:您可以在查询的where子句中包含?s,它将替换为selectionArgs中的值。这些值将绑定为字符串。

问号可以将不同的值绑定到预编译的SQL查询。此功能不适用于配置要在查询中使用的列。您的第一种方法是正确的方法。您可以将其中的2个设为动态:

db.rawQuery("Select Id, Disp, Tp From Funco Where Id<=?;", arrayOf("2"))