SQLiteStatement 执行一个 SELECT / INSERT / DELETE / UPDATE

Posted

技术标签:

【中文标题】SQLiteStatement 执行一个 SELECT / INSERT / DELETE / UPDATE【英文标题】:SQLiteStatement execute a SELECT / INSERT / DELETE / UPDATE 【发布时间】:2012-11-02 03:59:14 【问题描述】:

我在优化 SQLite 事务时使用了带有事务的编译 SQLiteStatement,但我正在阅读 execute 函数的文档:

执行这条SQL语句,如果不是SELECT/INSERT/DELETE/UPDATE,例如CREATE/DROP表、视图、触发器、索引等。

这似乎暗示这个函数不应该与SELECT / INSERT / DELETE / UPDATE 语句一起使用,但我有代码可以将它与插入一起使用并且可以工作。

我知道executeInsert 和其他方法,但是executeUpdateDelete 在我的API 级别中不可用,那么我可以使用execute 吗?

另外,如果我不需要最后一个插入 id 或受影响的行数,我应该使用execute 而不是executeInsert 等,换句话说,它更有效吗?

【问题讨论】:

【参考方案1】:

execute 可能不会比executeInsert 快,甚至可能更慢(在 ICS 上 execute 调用 executeUpdateDelete 并丢弃返回值)。您需要对其进行测试,但我怀疑您会在这里找到真正的区别。

AFAIK,如果您不需要返回值,则仅使用 execute 是安全的,但我不会指望在未来的 android 版本中保持这种状态。文档说不,所以也许有人会改变行为以反映这一点。较旧的实现似乎也使用execute(例如2.1 delete() sourcecode)。例如,Jelly Bean 在 SQLite 的幕后更改了 a lot,但在使用 execute 时它仍然可以工作

此外,如果您不一遍又一遍地使用相同的 SQLiteStatement 而只是重新绑定 args,那么它可能不值得使用它。与实际的数据库访问和所需的磁盘 I/O 相比,每次调用常规的 insertupdate、... 方法时都构建一个新的。另一方面,事务有很大帮助,因为在磁盘上为每个语句同步数据库状态真的很慢。

【讨论】:

所以你的意思是不能保证execute() 将在未来发布也与INSERT statement 一起工作而且文档只是混淆它说它Execute this SQL statement, if it is not a SELECT / INSERT /.... 然后它不应该执行INSERT (因为这是我测试过的唯一声明)及其工作!并感谢您提供宝贵的信息:) 还有 statement.executeUpdateDelete(); 这在 API 11 中可用 2.2 的任何解决方法? @MuhammadBabar 该文档试图告诉您execute 方法不适用于有结果的语句。就像为选择设置的行一样,更新/删除的更改计数或插入的最后一行 ID。到目前为止,还没有任何代码可以防止这些意外语句起作用。也许未来对数据库架构的改变会发生,我不知道。 android 框架工程师可以在不通知的情况下轻松添加这样的更改,因为该方法的描述警告您,它多年来将无法工作。 在 2.2 中,获取更新/删除语句的结果更改计数的唯一方法是使用 SQLiteDatabase#update 或 delete。这些方法在内部对每个方法调用使用新的SQLiteStatement。他们使用SQLiteStatement#execute(),然后通过SQLiteDatabase 的隐藏方法记录更改计数。该隐藏方法最终在 API 11 中公开以供 SQLiteStatement 使用,但之前没有。 delete()executeUpdateDelete() 哪个更快?【参考方案2】:

使用SQLiteDatabase 而不是SQLiteStatement 与您的数据库进行交互。 SQLiteStatements 不是线程安全的,所以我不会将它们用于 SELECT / INSERT / DELETE / UPDATE。此外,您应该尽量不要将原始数据库查询用于Selects 以外的任何内容。有内置的辅助函数可以提高您的数据库性能。在您的 SQLiteDatabase 实例上,您有 .insert、.update、.delete,我使用 .rawQuery 进行选择。

【讨论】:

但不是THREAD-SAFE 仅暗示 多线程 应用程序。对于单线程,如果您想要批量插入,则值得使用。 嗯,每个带有数据库的应用程序都应该是多线程的。对磁盘、数据库或 Web 服务的任何请求都应脱离 UI 线程。如果您阻止 UI 线程进行批量插入,那么您做错了。 @JustinMorris:如果只有一个工作线程访问数据库,调用非线程安全方法就可以了。应用程序是多线程的这一事实不是问题,因为主线程不访问数据库。

以上是关于SQLiteStatement 执行一个 SELECT / INSERT / DELETE / UPDATE的主要内容,如果未能解决你的问题,请参考以下文章

SQLiteStatements 是不是需要关闭?

sele nium 模块

EXPLAIN 执行计划详解

按每月的每个周执行SQL查询

改进 postgresql 选择请求执行时间

Mysql - 查询之关联查询