我正在尝试执行参数化查询以插入/更新/删除,就像使用rawQuery(String sql,String []参数)进行选择一样.我需要通过查询而不是在sqliteDatabase类上使用insert / update / delete方法来执行此操作,因为在许多情况下,查询跨越多个表,并且在任何情况下我们都编写了一组我们用于此app的查询在我们所有的平台上(也为sqlite编写),最好是按原样使用它.
这是我发现令人困惑/误导的内容:
> doc告诉rawQuery语句不能用分号终止,但它实际上似乎没有任何区别.这对我很重要,因为我们有一个巨大的XML文档,里面填充了我在我的应用程序中跨多个平台使用的查询,如果可能的话,我更愿意保持相同.
> rawQuery似乎不适用于插入(是的,我尝试使用和不使用分号).该文件没有说明这一点.我确实看到它返回一个Cursor,我想这可能是一个倾斜提示,它只适用于select,但不一定 – 它可以简单地返回零长度或null Cursor,当它们没有结果集时.
> execsql(String sql,Object [] bindArgs)明确表示它不适用于插入,但事实上确实如此!
>此外,尽管execsql(String,Object [])明确告诉您不要尝试CRUD操作,但它的无参数版本不包含此类警告,并且也可以正常工作(缺点是不允许sql参数).
所有这一切的结果是,我能够找到成功执行带参数化参数的插入的唯一方法是使用文档明确指示您不要用于此目的的一种工作方法.
另外,对于插入/更新/删除来说,rawQuery无法正常工作,因为我们有一个通用的数据层,如果我们可以使用单个统一的API调用来运行我们所有的CRUD查询,那将更加优雅.数据库.
那么这里发生了什么?这份文件是否已经过时了?是否可以使用execsql来执行插入,更新等操作?有没有人成功使用rawQuery进行插入?
附录:
针对OS运行:Android 4.3.
示例查询(什么工作,什么不工作)
// Works db.execsql("INSERT into MyTable (Col1,Col2) VALUES (?,?)",new String[] { "Foo","Bar" }); db.execsql("INSERT into MyTable (Col1,?);","Bar" }); // No exception thrown,but no changes made to the database db.rawQuery("INSERT into MyTable (Col1,"Bar" }); db.rawQuery("INSERT into MyTable (Col1,"Bar" });
解决方法
The doc says for
rawQuery
that statements must not be terminated by a semicolon,but it doesn’t actually seem to make any difference. This matters to me because we have a huge XML document filled with queries I use in my app across several platforms and I’d prefer to keep it identical if possible.
文档很糟糕.实际上,Android sqliteDatabase本身就是calls rawQuery
with a semicolon-terminated query string.
rawQuery
doesn’t seem to work for inserts (yes,I’ve tried with and without the semicolon). The doc don’t say anything about this. I do see that it returns a Cursor,which I suppose could be an oblique hint that it only works with a select,but not necessarily — it could simply return a zero-length or null Cursor when they was no result set.
它确实有效,但您需要了解它在本机级别上的工作原理.
将execsql()视为运行查询的sqlite3_exec()
并返回成功或错误代码.
将rawQuery()视为编译查询但尚未运行的sqlite3_prepare()
.要实际运行它,请使用Cursor上的moveTo …()方法之一.可以将其视为sqlite3_step()
.将任何rawQuery()与moveTo …()组合将实际改变数据库.
execsql(String sql,Object[] bindArgs)
explicitly says that it does not work with selects,but in fact it does!Furthermore,although
execsql(String,Object[])
specifically tells you not to try CRUD operations,its parameterless version contains no such warning,and also works fine for that purpose (with the disadvantage of not allowing sql parameters).
它适用于所有CRUD操作.对于CRUD的R读取部分,无法获得所选数据.