当前位置: 首页 > 面试题库 >

使用查询字符串在Android SQLiteDatabase中执行插入/更新/删除的正确方法是什么?

熊朝
2023-03-14
问题内容

我一直在看官方文档(http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html)并与StackOverflow帖子和实际观察到的行为进行交叉引用,并且该文档似乎是在某些方面具有误导性,甚至可能是错误的。

我正在尝试执行参数化查询来插入/更新/删除,就像选择rawQuery(String sql, String[] arguments).要执行的操作一样,我需要通过查询而不是通过使用SQLiteDatabase类上的insert / update /
delete方法来进行选择,因为在许多情况下,查询跨越多个表,在任何情况下,我们都在所有平台上编写了用于此应用程序的大量查询(也为SQLite编写),因此按原样使用它是更可取的。

这是我感到困惑/误导的地方:

  • 该文档说,rawQuery该语句 不能 以分号结尾,但实际上似乎没有任何区别。这对我来说很重要,因为我们有一个巨大的XML文档,其中填充了我在多个平台上的应用程序中使用的查询,并且我希望尽可能保持相同。

  • rawQuery似乎不适用于插入内容(是的,我尝试使用和不使用分号)。这位医生对此一无所知。我确实看到它返回了一个Cursor,我想这可能是一个斜线提示,它仅适用于select,但不一定如此-当没有结果集时,它可以简单地返回零长度或null的Cursor。

  • execSQL(String sql, Object[] bindArgs)明确地说,它并 没有 与插入工作,但实际上它呢!

  • 此外,尽管execSQL(String, Object[])明确告诉您不要尝试CRUD操作,但其无参数版本不包含此类警告,并且也可以正常工作(缺点是不允许使用SQL参数)。

所有这些的结果是,我能找到的成功执行带有参数化参数的插入的唯一方法是使用 docs明确指示您 不要 用于该目的的一种工作方法。

另外,rawQuery不适用于插入/更新/删除,真是令人不寒而栗,因为我们有一个通用的数据层,如果我们可以使用一个统一的API调用来在数据库。

那么这是怎么回事?该文档是否过时了?使用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, 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" });

问题答案:

你是对的。该文档令人困惑。总体而言,该设计尝试围绕sqlite3 C
API提供一个方便的Java包装器。在大多数情况下,如果按照设计人员的预期使用它(例如使用CRUD操作的便捷方法),它就可以正常工作。但是,他们还需要提供原始查询方法,execSQL()以及rawQuery()在便利性CRUD方法功能不足或根本不适用的情况下(CREATE TABLE等等)。这导致泄漏抽象。

该文档说,rawQuery该语句不能以分号结尾,但实际上似乎没有任何区别。这对我来说很重要,因为我们有一个巨大的XML文档,其中填充了我在多个平台上的应用程序中使用的查询,并且我希望尽可能保持相同。

该文档是不好的。实际上,Android
SQLiteDatabase本身使用分号终止的查询字符串进行调用rawQuery

rawQuery似乎不适用于插入内容(是的,我尝试使用和不使用分号)。这位医生对此一无所知。我确实看到它返回了一个Cursor,我想这可能是一个斜线提示,它仅适用于select,但不一定如此-
当没有结果集时,它可以简单地返回零长度或null的Cursor。

确实可以 工作,但是您需要了解它在本机级别如何工作。

想想execSQL()作为sqlite3_exec()运行查询,并返回成功或错误代码。

可以认为rawQuery()sqlite3_prepare()可以编译查询但尚未运行它。要实际运行它,请使用上的一种moveTo...()方法Cursor。认为这是sqlite3_step()。结合任何rawQuery()moveTo...()居然会改变数据库。

execSQL(String sql, Object[] bindArgs) 明确表示它不适用于选择,但实际上可以!

此外,尽管execSQL(String, Object[])明确告诉您不要尝试CRUD操作,但其无参数版本不包含此类警告,并且也可以正常工作(缺点是不允许使用SQL参数)。

它适用于所有CRUD操作。对于CRUD的R读取部分,根本无法获取所选数据



 类似资料:
  • 关于这个问题有好几篇帖子,但仍然没有找到答案。这是父类Userr。在@OneToMany关系中,我想删除一个特定的子帐户。 现在,当我通过“删除”查询执行此操作时,我得到以下异常。 组织。springframework。刀。InvalidDataAccessApiUsageException:执行更新/删除查询;嵌套的异常是javax。坚持不懈TransactionRequiredExceptio

  • 我正在尝试使用query-更新行(删除列str_column中的连字符和连字符后的所有字符)- 但上面的查询是删除匹配的行而不是更新。 我不明白,如何更新查询可以删除行??

  • 问题内容: 我在Spring和mongodb中使用了hibernate JPA,并且我在Glassfish-4.0上运行我的应用程序。 我的服务类别是: 我的spring-context.xml是: 我在代码中应用了一些更改,但是它们没有效果。谁能帮我解决这个问题。提前致谢。 问题答案: 我不确定这是否会帮助你解决问题(即是否仍然存在),但是,在网上搜索类似问题之后。 我从持久性EntityMan

  • 问题内容: 我有一个简单的问题:假设有一个查询如下的站点: 。 有什么办法可以在数据库(MySQL)中更新/删除某些内容?到现在为止,我还从未见过能够使用 SELECT查询 删除/更新的注入,所以,甚至有可能吗? 问题答案: 如果您说使用了不支持多个查询的内容,则不能直接添加/ / ,但是在某些情况下可以修改数据。例如,假设您具有以下功能 现在您可以在以下位置调用此函数: (--始终为NULL(F

  • 插入、更新和删除语句基于以开头的层次结构生成 UpdateBase . 这个 Insert 和 Update 构建基于中介的 ValuesBase . DML基础构造函数 顶级的“插入”、“更新”、“删除”构造函数。 Object Name Description delete(table[, whereclause, bind, returning, ...], **dialect_kw) 构建

  • 我想在SQLite查询的每个ORDER BY子句之前插入一个COLLATE NOCASE。这就是我到目前为止所拥有的: 输出为: 从'test'顺序中选择'x','y',按'x'整理NOCASE ASC,'z'ASC限制0,10 第一个实例被匹配和替换。第二个实例不被替换(因为模式中的ORDER BY子句)。