是什么做的插入/更新的正确方法/使用查询字符串的Andr​​oid SQLiteDatabase删除? [英] What is the correct way to do inserts/updates/deletes in Android SQLiteDatabase using a query string?

查看:193
本文介绍了是什么做的插入/更新的正确方法/使用查询字符串的Andr​​oid SQLiteDatabase删除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找的官方文档(的http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html)和交叉参考的StackOverflow职位与实际观察到的行为,和文档似乎是误导性的,可能只是错在几个方面。

我试图执行参数化查询插入/更新/删除,只是因为人们可能做到与 rawQuery选择(字符串SQL,字符串[]参数)。我需要通过一个查询,而不是通过插入/更新/删除,因为在很多情况下在SQLiteDatabase类的方法查询跨越多个表,并在任何情况下,我们已经写了一大套,我们为这个应用程序在整个使用查询来做到这一点我们所有的平台(也写了SQLite的),这将是非常preferable使用它就好了。

这是我感到迷惑/误导性:

  • 该医生说了 rawQuery 的声明必须的不可以它实际上并不似乎并用分号终止,反而使任何区别。这很重要,对我来说,因为我们有充满疑问跨越多个平台我在我的应用程序中使用,我想preFER以保持相同的,如果可能的一个巨大的XML文档。

  • rawQuery 似乎不工作插入(是的,我试过有和没有分号)。该文档不说这事。我也看到它返回一个指针,我想可能是一个倾斜的提示,它只有一个选择工作,但不一定是 - 它可以简单地返回一个零长度或空光标时,他们是没有结果集

  • execSQL(字符串SQL,对象[] bindArgs)明确地说,它的不可以的工作与插入,但实际上它的确!

  • 此外,虽然 execSQL(字符串,对象[])明确告诉你不要尝试CRUD操作,其参数的版本中没有这样的警告,也适用罚款的目的(含未允许SQL参数的缺点)。

这一切的结果是,我能找到成功地与参数化的参数执行插入的唯一方法是使用,该文档明确指示一个工作方法,你的没有的使用用于这一目的。

此外,这真是一个令人失望的rawQuery不会为插入工作/更新/删除,因为我们有一个通用的数据层,这将是更优雅,如果我们可以用一个单一的,统一的API调用来运行所有的CRUD查询在数据库上。

那么,什么是怎么回事?这是文档无可救药地过时了?它是好的用execSql做插入,更新,等等?有没有人成功地做到了刀片与rawQuery?


附录:

运行针对操作系统:Android的4.3

示例查询(什么是工作,什么是不)

  //作品
db.execSql(INSERT INTO MyTable的(COL1,col2的)VALUES(,)?,新的String [] {富,酒吧});
db.execSql(INSERT INTO MyTable的(COL1,col2的)VALUES(,);?,新的String [] {富,酒吧});

//没有抛出异常,但没有改变对数据库所做
db.rawQuery(INSERT INTO MyTable的(COL1,col2的)VALUES(,)?,新的String [] {富,酒吧});
db.rawQuery(INSERT INTO MyTable的(COL1,col2的)VALUES(,);?,新的String [] {富,酒吧});
 

解决方案

你是对的。该文档是令人困惑的。总体而言,设计试图提供各地的sqlite3的C API方便的Java包装。对于大多数的时候,如果你使用它的方式,设计师意,如工作正常使用便利的方法CRUD操作。但他们也需要提供原始的查询方法 execSQL() rawQuery()为那里的方便CRUD方法的情况下不够或不适用在所有强大的( CREATE TABLE 等)。这将导致漏水的抽象。

  

该医生说了 rawQuery 的语句不能以分号结束,但它实际上并不似乎使任何区别呢。这很重要,对我来说,因为我们有充满疑问跨越多个平台我在我的应用程序中使用,我想preFER以保持相同的,如果可能的一个巨大的XML文档。

该文档是坏的。事实上,Android的 SQLiteDatabase 自身<一href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.3_r2.1/android/database/sqlite/SQLiteDatabase.java#2090"相对=nofollow>电话 rawQuery 以分号结尾的查询字符串。

  

rawQuery 似乎并没有工作插入(是的,我试过有和没有分号)。该文档不说这事。我也看到它返回一个指针,我想可能是一个倾斜的提示,它只有一个选择工作,但不一定是 - 它可以简单地返回一个零长度或空光标时,他们是没有结果集

它的确实的工作,但你需要了解它是如何工作的母语水平。

想想 execSQL() sqlite3_exec() 运行查询,并返回成功或错误code。

想想 rawQuery()作为的 sqlite3_ prepare() 来编译查询,但不运行它。要真正运行它,使用对光标 MOVETO ..​​.()的方法之一。认为这是 sqlite3_step() 。结合任何 rawQuery() MOVETO ..​​.()将真正改变数据库。

  

execSQL(SQL字符串,对象[] bindArgs)明确地说,它不与选择工作,但实际上它确实!

     

此外,虽然 execSQL(字符串,对象[])明确告诉你不要尝试CRUD操作,其参数的版本中没有这样的警告,也能正常工作为目的(含未允许SQL参数的缺点)。

它工作正常的所有​​CRUD操作。对于R读取CRUD的一部分,只是没有办法让选定的数据。

I've been looking at the official documentation (http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html) and cross-referencing with StackOverflow posts and actual observed behavior, and the documentation seems to be misleading and possibly just wrong in several respects.

I am trying to perform parameterized queries to insert/update/delete, just as one might do for selecting with rawQuery(String sql, String[] arguments). I need to do it via a query rather than by using the insert/update/delete methods on the SQLiteDatabase class because in many cases the queries span multiple tables and in any case we have written a large set of queries that we use for this app across all our platforms (also written for SQLite), and it would be highly preferable to use it as-is.

Here's what I find confusing/misleading:

  • 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.

  • 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(String sql, Object[] bindArgs) explicitly says that it does not work with inserts, 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).

The result of all of this is that the only way I can find to successfully execute inserts with parametrized arguments is to use the one working method that the docs explicitly instruct you not to use for that purpose.

Also, it's really a bummer that rawQuery won't work for inserts/updates/deletes, because we have a generalized data layer and it would be more elegant if we could use a single, unified API call to run all our CRUD queries on the database.

So what is going on here? Is this documentation hopelessly out of date? Is it okay to use execSql to do inserts, updates, and so on? Has anyone succeeded in doing inserts with rawQuery?


Appendix:

Running against OS: Android 4.3.

Sample queries (what's working, what's not)

// Works
db.execSql("INSERT into MyTable (Col1, Col2) VALUES (?, ?)", new String[] { "Foo", "Bar" });
db.execSql("INSERT into MyTable (Col1, Col2) VALUES (?, ?);", new String[] { "Foo", "Bar" });

// No exception thrown, but no changes made to the database
db.rawQuery("INSERT into MyTable (Col1, Col2) VALUES (?, ?)", new String[] { "Foo", "Bar" });
db.rawQuery("INSERT into MyTable (Col1, Col2) VALUES (?, ?);", new String[] { "Foo", "Bar" });

解决方案

You are right. The documentation is confusing. Overall, the design attempts to provide a convenient Java wrapper around the sqlite3 C API. For most of the time it works fine if you use it the way the designers intended, e.g. using the convenience methods for CRUD operations. But they also needed to provide raw query methods execSQL() and rawQuery() for cases where the convenience CRUD methods are not powerful enough or not applicable at all (CREATE TABLE and so on). This causes leaky abstractions.

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.

The docs are bad. In fact, Android SQLiteDatabase itself 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.

It does work but you'll need to understand how it works on native level.

Think of execSQL() as sqlite3_exec() that runs the query and returns either success or an error code.

Think of rawQuery() as sqlite3_prepare() that compiles the query but does not run it yet. To actually run it, use one of the moveTo...() methods on the Cursor. Think of this as sqlite3_step(). Combining any rawQuery() with moveTo...() will actually alter the database.

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).

It works fine for all CRUD operations. For the R read part of CRUD, there's just no way to get the selected data.

这篇关于是什么做的插入/更新的正确方法/使用查询字符串的Andr​​oid SQLiteDatabase删除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆